mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-11-22 06:35:57 +01:00
Bind toplevel protos once before first screencast
Also style.
This commit is contained in:
parent
b03b1c2f27
commit
ee73fca9cc
3 changed files with 1232 additions and 1235 deletions
|
@ -6,9 +6,9 @@
|
|||
#include <spa/param/video/format-utils.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <xf86drm.h>
|
||||
#include "hyprland-toplevel-export-v1-client-protocol.h"
|
||||
|
||||
#include "fps_limit.h"
|
||||
#include "hyprland-toplevel-export-v1-client-protocol.h"
|
||||
|
||||
// this seems to be right based on
|
||||
// https://github.com/flatpak/xdg-desktop-portal/blob/309a1fc0cf2fb32cceb91dbc666d20cf0a3202c2/src/screen-cast.c#L955
|
||||
|
@ -105,7 +105,6 @@ struct xdpw_dmabuf_feedback_data {
|
|||
};
|
||||
|
||||
struct xdpw_screencast_context {
|
||||
|
||||
// xdpw
|
||||
struct xdpw_state *state;
|
||||
|
||||
|
@ -128,6 +127,7 @@ struct xdpw_screencast_context {
|
|||
struct hyprland_toplevel_export_manager_v1 *hyprland_toplevel_manager;
|
||||
struct zwlr_foreign_toplevel_manager_v1 *wlroots_toplevel_manager;
|
||||
struct wl_list toplevel_resource_list;
|
||||
int toplevel_mgr_bind;
|
||||
|
||||
// gbm
|
||||
struct gbm_device *gbm;
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
#include "screencast.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <drm_fourcc.h>
|
||||
#include <errno.h>
|
||||
#include <spa/utils/result.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <drm_fourcc.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <spa/utils/result.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "pipewire_screencast.h"
|
||||
#include "wlr_screencast.h"
|
||||
#include "xdpw.h"
|
||||
#include "logger.h"
|
||||
|
||||
static const char object_path[] = "/org/freedesktop/portal/desktop";
|
||||
static const char interface_name[] = "org.freedesktop.impl.portal.ScreenCast";
|
||||
|
@ -49,7 +49,6 @@ void exec_with_shell(char *command) {
|
|||
|
||||
void xdpw_screencast_instance_init(struct xdpw_screencast_context *ctx,
|
||||
struct xdpw_screencast_instance *cast, struct xdpw_share out, bool with_cursor) {
|
||||
|
||||
// only run exec_before if there's no other instance running that already ran it
|
||||
if (wl_list_empty(&ctx->screencast_instances)) {
|
||||
char *exec_before = ctx->state->config->screencast_conf.exec_before;
|
||||
|
@ -65,8 +64,7 @@ void xdpw_screencast_instance_init(struct xdpw_screencast_context *ctx,
|
|||
cast->max_framerate = 60; // dirty
|
||||
} else {
|
||||
if (ctx->state->config->screencast_conf.max_fps > 0) {
|
||||
cast->max_framerate = ctx->state->config->screencast_conf.max_fps < (uint32_t)out.output->framerate ?
|
||||
ctx->state->config->screencast_conf.max_fps : (uint32_t)out.output->framerate;
|
||||
cast->max_framerate = ctx->state->config->screencast_conf.max_fps < (uint32_t)out.output->framerate ? ctx->state->config->screencast_conf.max_fps : (uint32_t)out.output->framerate;
|
||||
} else {
|
||||
cast->max_framerate = (uint32_t)out.output->framerate;
|
||||
}
|
||||
|
@ -114,7 +112,6 @@ void xdpw_screencast_instance_teardown(struct xdpw_screencast_instance *cast) {
|
|||
}
|
||||
|
||||
bool setup_outputs(struct xdpw_screencast_context *ctx, struct xdpw_session *sess, bool with_cursor) {
|
||||
|
||||
struct xdpw_wlr_output *output, *tmp_o;
|
||||
wl_list_for_each_reverse_safe(output, tmp_o, &ctx->output_list, link) {
|
||||
logprint(INFO, "wlroots: capturable output: %s model: %s: id: %i name: %s",
|
||||
|
@ -164,9 +161,7 @@ bool setup_outputs(struct xdpw_screencast_context *ctx, struct xdpw_session *ses
|
|||
logprint(INFO, "hyprland: window handle %d", sess->screencast_instance->target.window_handle);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
static int start_screencast(struct xdpw_screencast_instance *cast) {
|
||||
|
@ -175,6 +170,7 @@ static int start_screencast(struct xdpw_screencast_instance *cast) {
|
|||
// process at least one frame so that we know
|
||||
// some of the metadata required for the pipewire
|
||||
// remote state connected event
|
||||
cast->ctx->toplevel_mgr_bind = 1;
|
||||
wl_display_dispatch(cast->ctx->state->wl_display);
|
||||
wl_display_roundtrip(cast->ctx->state->wl_display);
|
||||
|
||||
|
@ -318,7 +314,7 @@ static int method_screencast_select_sources(sd_bus_message *msg, void *data,
|
|||
} else if (strcmp(key, "types") == 0) {
|
||||
uint32_t mask;
|
||||
sd_bus_message_read(msg, "v", "u", &mask);
|
||||
if (mask & (1<<WINDOW)) {
|
||||
if (mask & (1 << WINDOW)) {
|
||||
logprint(INFO, "dbus: non-monitor cast requested, not replying");
|
||||
return -1;
|
||||
}
|
||||
|
@ -518,15 +514,15 @@ static const sd_bus_vtable screencast_vtable[] = {
|
|||
SD_BUS_PROPERTY("version", "u", NULL,
|
||||
offsetof(struct xdpw_state, screencast_version),
|
||||
SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
SD_BUS_VTABLE_END};
|
||||
|
||||
int xdpw_screencast_init(struct xdpw_state *state) {
|
||||
sd_bus_slot *slot = NULL;
|
||||
|
||||
state->screencast = (struct xdpw_screencast_context) { 0 };
|
||||
state->screencast = (struct xdpw_screencast_context){0};
|
||||
state->screencast.state = state;
|
||||
state->screencast.hyprland_toplevel_manager = NULL;
|
||||
state->screencast.toplevel_mgr_bind = 0;
|
||||
|
||||
int err;
|
||||
err = xdpw_pwr_context_create(state);
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
#include "wlr_screencast.h"
|
||||
|
||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||
#include "wlr-screencopy-unstable-v1-client-protocol.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
#include "wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
|
||||
#include "hyprland-toplevel-export-v1-client-protocol.h"
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -15,16 +11,19 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <xf86drm.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "screencast.h"
|
||||
#include "pipewire_screencast.h"
|
||||
#include "xdpw.h"
|
||||
#include "logger.h"
|
||||
#include "fps_limit.h"
|
||||
#include "hyprland-toplevel-export-v1-client-protocol.h"
|
||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||
#include "logger.h"
|
||||
#include "pipewire_screencast.h"
|
||||
#include "screencast.h"
|
||||
#include "wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
|
||||
#include "wlr-screencopy-unstable-v1-client-protocol.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
#include "xdpw.h"
|
||||
//
|
||||
|
||||
struct SToplevelEntry {
|
||||
|
@ -58,6 +57,8 @@ void handleAppID(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, con
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
logprint(DEBUG, "hyprland: toplevel app_id %s", app_id);
|
||||
}
|
||||
|
||||
void handleOutputEnter(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, struct wl_output *output) {
|
||||
|
@ -86,6 +87,8 @@ void handleClosed(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle) {
|
|||
}
|
||||
}
|
||||
|
||||
logprint(DEBUG, "hyprland: toplevel closed %s", current->clazz);
|
||||
|
||||
wl_list_remove(¤t->link);
|
||||
}
|
||||
|
||||
|
@ -107,17 +110,19 @@ struct zwlr_foreign_toplevel_handle_v1_listener toplevelHandleListener = {
|
|||
void handleToplevel(void *data, struct zwlr_foreign_toplevel_manager_v1 *manager, struct zwlr_foreign_toplevel_handle_v1 *toplevel) {
|
||||
struct xdpw_screencast_context *ctx = data;
|
||||
|
||||
struct SToplevelEntry* entry = malloc(sizeof(struct SToplevelEntry));
|
||||
struct SToplevelEntry *entry = malloc(sizeof(struct SToplevelEntry));
|
||||
|
||||
entry->handle = toplevel;
|
||||
|
||||
wl_list_insert(&ctx->toplevel_resource_list, &entry->link);
|
||||
|
||||
zwlr_foreign_toplevel_handle_v1_add_listener(toplevel, &toplevelHandleListener, ctx);
|
||||
|
||||
logprint(DEBUG, "hyprland: toplevel handle created %lx", toplevel);
|
||||
}
|
||||
|
||||
void handleFinished(void *data, struct zwlr_foreign_toplevel_manager_v1 *zwlr_foreign_toplevel_manager_v1) {
|
||||
; // noop
|
||||
logprint(ERROR, "hyprland: compositor called finished on zwlr_foreign_toplevel_manager_v1!");
|
||||
}
|
||||
|
||||
struct zwlr_foreign_toplevel_manager_v1_listener toplevelListener = {
|
||||
|
@ -125,7 +130,7 @@ struct zwlr_foreign_toplevel_manager_v1_listener toplevelListener = {
|
|||
.finished = handleFinished,
|
||||
};
|
||||
|
||||
struct SToplevelEntry* toplevelEntryFromID(struct xdpw_screencast_context *ctx, uint32_t id) {
|
||||
struct SToplevelEntry *toplevelEntryFromID(struct xdpw_screencast_context *ctx, uint32_t id) {
|
||||
struct SToplevelEntry *current;
|
||||
wl_list_for_each(current, &ctx->toplevel_resource_list, link) {
|
||||
if (((uint64_t)current->handle & 0xFFFFFFFF) == id) {
|
||||
|
@ -177,7 +182,7 @@ void xdpw_wlr_frame_finish(struct xdpw_screencast_instance *cast) {
|
|||
uint64_t delay_ns = fps_limit_measure_end(&cast->fps_limit, cast->framerate);
|
||||
if (delay_ns > 0) {
|
||||
xdpw_add_timer(cast->ctx->state, delay_ns,
|
||||
(xdpw_event_loop_timer_func_t) xdpw_wlr_frame_start, cast);
|
||||
(xdpw_event_loop_timer_func_t)xdpw_wlr_frame_start, cast);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -277,7 +282,7 @@ static void wlr_frame_buffer_done(void *data,
|
|||
assert(cast->current_frame.xdpw_buffer);
|
||||
|
||||
// Check if dequeued buffer is compatible with announced buffer
|
||||
if (( cast->buffer_type == WL_SHM &&
|
||||
if ((cast->buffer_type == WL_SHM &&
|
||||
(cast->current_frame.xdpw_buffer->size[0] != cast->screencopy_frame_info[cast->buffer_type].size ||
|
||||
cast->current_frame.xdpw_buffer->stride[0] != cast->screencopy_frame_info[cast->buffer_type].stride)) ||
|
||||
cast->current_frame.xdpw_buffer->width != cast->screencopy_frame_info[cast->buffer_type].width ||
|
||||
|
@ -331,7 +336,7 @@ static void wlr_frame_ready(void *data, struct zwlr_screencopy_frame_v1 *frame,
|
|||
|
||||
cast->current_frame.tv_sec = ((((uint64_t)tv_sec_hi) << 32) | tv_sec_lo);
|
||||
cast->current_frame.tv_nsec = tv_nsec;
|
||||
logprint(TRACE, "wlroots: timestamp %"PRIu64":%"PRIu32, cast->current_frame.tv_sec, cast->current_frame.tv_nsec);
|
||||
logprint(TRACE, "wlroots: timestamp %" PRIu64 ":%" PRIu32, cast->current_frame.tv_sec, cast->current_frame.tv_nsec);
|
||||
|
||||
cast->frame_state = XDPW_FRAME_STATE_SUCCESS;
|
||||
|
||||
|
@ -438,7 +443,7 @@ static void hyprland_frame_buffer_done(void *data,
|
|||
assert(cast->current_frame.xdpw_buffer);
|
||||
|
||||
// Check if dequeued buffer is compatible with announced buffer
|
||||
if (( cast->buffer_type == WL_SHM &&
|
||||
if ((cast->buffer_type == WL_SHM &&
|
||||
(cast->current_frame.xdpw_buffer->size[0] != cast->screencopy_frame_info[cast->buffer_type].size ||
|
||||
cast->current_frame.xdpw_buffer->stride[0] != cast->screencopy_frame_info[cast->buffer_type].stride)) ||
|
||||
cast->current_frame.xdpw_buffer->width != cast->screencopy_frame_info[cast->buffer_type].width ||
|
||||
|
@ -492,7 +497,7 @@ static void hyprland_frame_ready(void *data, struct hyprland_toplevel_export_fra
|
|||
|
||||
cast->current_frame.tv_sec = ((((uint64_t)tv_sec_hi) << 32) | tv_sec_lo);
|
||||
cast->current_frame.tv_nsec = tv_nsec;
|
||||
logprint(TRACE, "hyprland: timestamp %"PRIu64":%"PRIu32, cast->current_frame.tv_sec, cast->current_frame.tv_nsec);
|
||||
logprint(TRACE, "hyprland: timestamp %" PRIu64 ":%" PRIu32, cast->current_frame.tv_sec, cast->current_frame.tv_nsec);
|
||||
|
||||
cast->frame_state = XDPW_FRAME_STATE_SUCCESS;
|
||||
|
||||
|
@ -520,11 +525,9 @@ static const struct hyprland_toplevel_export_frame_v1_listener hyprland_frame_li
|
|||
.flags = hyprland_frame_flags,
|
||||
.ready = hyprland_frame_ready,
|
||||
.failed = hyprland_frame_failed,
|
||||
.damage = hyprland_frame_damage
|
||||
};
|
||||
.damage = hyprland_frame_damage};
|
||||
|
||||
void xdpw_wlr_register_cb(struct xdpw_screencast_instance *cast) {
|
||||
|
||||
if (cast->target.x != -1 && cast->target.y != -1 && cast->target.w != -1 && cast->target.h != -1 && cast->target.window_handle == -1) {
|
||||
// capture region
|
||||
cast->frame_callback = zwlr_screencopy_manager_v1_capture_output_region(
|
||||
|
@ -535,7 +538,7 @@ void xdpw_wlr_register_cb(struct xdpw_screencast_instance *cast) {
|
|||
cast->ctx->screencopy_manager, cast->with_cursor, cast->target.output->output);
|
||||
} else {
|
||||
// share window
|
||||
struct SToplevelEntry* entry = toplevelEntryFromID(cast->ctx, cast->target.window_handle);
|
||||
struct SToplevelEntry *entry = toplevelEntryFromID(cast->ctx, cast->target.window_handle);
|
||||
|
||||
if (!entry) {
|
||||
logprint(DEBUG, "hyprland: error in getting entry");
|
||||
|
@ -569,7 +572,7 @@ static void wlr_output_handle_mode(void *data, struct wl_output *wl_output,
|
|||
uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
|
||||
if (flags & WL_OUTPUT_MODE_CURRENT) {
|
||||
struct xdpw_wlr_output *output = data;
|
||||
output->framerate = (float)refresh/1000;
|
||||
output->framerate = (float)refresh / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -670,14 +673,12 @@ char *getFormat(const char *fmt, ...) {
|
|||
return outputStr;
|
||||
}
|
||||
|
||||
char* buildWindowList(struct xdpw_screencast_context *ctx) {
|
||||
char *buildWindowList(struct xdpw_screencast_context *ctx) {
|
||||
char *rolling = calloc(1, 1);
|
||||
|
||||
char* rolling = calloc(1, 1);
|
||||
|
||||
struct SToplevelEntry* current;
|
||||
struct SToplevelEntry *current;
|
||||
wl_list_for_each(current, &ctx->toplevel_resource_list, link) {
|
||||
|
||||
char* oldRolling = rolling;
|
||||
char *oldRolling = rolling;
|
||||
|
||||
rolling = getFormat("%s%u[HC\011]%s[HT\011]%s[HE\011]", rolling, (uint32_t)(((uint64_t)current->handle) & 0xFFFFFFFF), current->clazz, current->name);
|
||||
|
||||
|
@ -701,7 +702,7 @@ struct xdpw_share xdpw_wlr_chooser(struct xdpw_screencast_context *ctx) {
|
|||
const char *XCURSOR_SIZE = getenv("XCURSOR_SIZE");
|
||||
const char *HYPRLAND_INSTANCE_SIGNATURE = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||
|
||||
char* windowList = buildWindowList(ctx);
|
||||
char *windowList = buildWindowList(ctx);
|
||||
|
||||
char *cmd = getFormat("WAYLAND_DISPLAY=%s QT_QPA_PLATFORM=\"wayland\" XCURSOR_SIZE=%s HYPRLAND_INSTANCE_SIGNATURE=%s XDPH_WINDOW_SHARING_LIST=\"%s\" hyprland-share-picker", WAYLAND_DISPLAY, XCURSOR_SIZE ? XCURSOR_SIZE : "24", HYPRLAND_INSTANCE_SIGNATURE ? HYPRLAND_INSTANCE_SIGNATURE : "0", windowList);
|
||||
|
||||
|
@ -731,11 +732,11 @@ struct xdpw_share xdpw_wlr_chooser(struct xdpw_screencast_context *ctx) {
|
|||
// find output
|
||||
logprint(DEBUG, "Screencast: Attempting to find screen for %s", result);
|
||||
|
||||
char* display_name = malloc(strlen(result) - 7);
|
||||
char *display_name = malloc(strlen(result) - 7);
|
||||
strncpy(display_name, result + 7, strlen(result) - 8);
|
||||
display_name[strlen(result) - 8] = 0;
|
||||
|
||||
struct xdpw_wlr_output* out;
|
||||
struct xdpw_wlr_output *out;
|
||||
bool found = false;
|
||||
wl_list_for_each(out, &ctx->output_list, link) {
|
||||
if (strcmp(out->name, display_name) == 0) {
|
||||
|
@ -757,7 +758,7 @@ struct xdpw_share xdpw_wlr_chooser(struct xdpw_screencast_context *ctx) {
|
|||
|
||||
int atPos = 7;
|
||||
for (int i = 7; i < (int)strlen(result); ++i) {
|
||||
if (result[i] == '@'){
|
||||
if (result[i] == '@') {
|
||||
atPos = i;
|
||||
break;
|
||||
}
|
||||
|
@ -780,7 +781,7 @@ struct xdpw_share xdpw_wlr_chooser(struct xdpw_screencast_context *ctx) {
|
|||
int coordbegin = 7 + strlen(display_name) + 1;
|
||||
for (int i = 7 + strlen(display_name) + 1; i < (int)strlen(result); ++i) {
|
||||
if (result[i] == ',' || result[i] == '@' || i + 1 == (int)strlen(result)) {
|
||||
char* entire = malloc(i - coordbegin + 1);
|
||||
char *entire = malloc(i - coordbegin + 1);
|
||||
strncpy(entire, result + coordbegin, i - coordbegin);
|
||||
entire[i - coordbegin] = 0;
|
||||
coords[coordno] = strtol(entire, NULL, 10);
|
||||
|
@ -922,7 +923,7 @@ static void linux_dmabuf_feedback_format_table(void *data,
|
|||
wl_array_release(&ctx->format_modifier_pairs);
|
||||
wl_array_init(&ctx->format_modifier_pairs);
|
||||
|
||||
ctx->feedback_data.format_table_data = mmap(NULL , size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
ctx->feedback_data.format_table_data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (ctx->feedback_data.format_table_data == MAP_FAILED) {
|
||||
ctx->feedback_data.format_table_data = NULL;
|
||||
ctx->feedback_data.format_table_size = 0;
|
||||
|
@ -991,7 +992,7 @@ static void linux_dmabuf_feedback_tranche_formats(void *data,
|
|||
// An entry in the table has to be 16 bytes long
|
||||
assert(sizeof(struct fm_entry) == 16);
|
||||
|
||||
uint32_t n_modifiers = ctx->feedback_data.format_table_size/sizeof(struct fm_entry);
|
||||
uint32_t n_modifiers = ctx->feedback_data.format_table_size / sizeof(struct fm_entry);
|
||||
struct fm_entry *fm_entry = ctx->feedback_data.format_table_data;
|
||||
uint16_t *idx;
|
||||
wl_array_for_each(idx, indices) {
|
||||
|
@ -1025,7 +1026,7 @@ static void wlr_registry_handle_add(void *data, struct wl_registry *reg,
|
|||
uint32_t id, const char *interface, uint32_t ver) {
|
||||
struct xdpw_screencast_context *ctx = data;
|
||||
|
||||
logprint(DEBUG, "wlroots: interface to register %s (Version: %u)",interface, ver);
|
||||
logprint(DEBUG, "wlroots: interface to register %s (Version: %u)", interface, ver);
|
||||
if (!strcmp(interface, wl_output_interface.name)) {
|
||||
struct xdpw_wlr_output *output = calloc(1, sizeof(*output));
|
||||
|
||||
|
@ -1052,7 +1053,7 @@ static void wlr_registry_handle_add(void *data, struct wl_registry *reg,
|
|||
reg, id, &zwlr_screencopy_manager_v1_interface, version);
|
||||
}
|
||||
|
||||
if (!strcmp(interface, hyprland_toplevel_export_manager_v1_interface.name)) {
|
||||
if (!strcmp(interface, hyprland_toplevel_export_manager_v1_interface.name) && !ctx->hyprland_toplevel_manager) {
|
||||
uint32_t version = ver;
|
||||
|
||||
logprint(DEBUG, "hyprland: |-- registered to interface %s (Version %u)", interface, version);
|
||||
|
@ -1060,7 +1061,7 @@ static void wlr_registry_handle_add(void *data, struct wl_registry *reg,
|
|||
ctx->hyprland_toplevel_manager = wl_registry_bind(reg, id, &hyprland_toplevel_export_manager_v1_interface, version);
|
||||
}
|
||||
|
||||
if (!strcmp(interface, zwlr_foreign_toplevel_manager_v1_interface.name)) {
|
||||
if (!strcmp(interface, zwlr_foreign_toplevel_manager_v1_interface.name) && ctx->toplevel_mgr_bind && !ctx->wlroots_toplevel_manager) {
|
||||
uint32_t version = ver;
|
||||
|
||||
logprint(DEBUG, "hyprland: |-- registered to interface %s (Version %u)", interface, version);
|
||||
|
|
Loading…
Reference in a new issue