mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-11-22 14: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 <spa/param/video/format-utils.h>
|
||||||
#include <wayland-client-protocol.h>
|
#include <wayland-client-protocol.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include "hyprland-toplevel-export-v1-client-protocol.h"
|
|
||||||
|
|
||||||
#include "fps_limit.h"
|
#include "fps_limit.h"
|
||||||
|
#include "hyprland-toplevel-export-v1-client-protocol.h"
|
||||||
|
|
||||||
// this seems to be right based on
|
// this seems to be right based on
|
||||||
// https://github.com/flatpak/xdg-desktop-portal/blob/309a1fc0cf2fb32cceb91dbc666d20cf0a3202c2/src/screen-cast.c#L955
|
// 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 {
|
struct xdpw_screencast_context {
|
||||||
|
|
||||||
// xdpw
|
// xdpw
|
||||||
struct xdpw_state *state;
|
struct xdpw_state *state;
|
||||||
|
|
||||||
|
@ -128,6 +127,7 @@ struct xdpw_screencast_context {
|
||||||
struct hyprland_toplevel_export_manager_v1 *hyprland_toplevel_manager;
|
struct hyprland_toplevel_export_manager_v1 *hyprland_toplevel_manager;
|
||||||
struct zwlr_foreign_toplevel_manager_v1 *wlroots_toplevel_manager;
|
struct zwlr_foreign_toplevel_manager_v1 *wlroots_toplevel_manager;
|
||||||
struct wl_list toplevel_resource_list;
|
struct wl_list toplevel_resource_list;
|
||||||
|
int toplevel_mgr_bind;
|
||||||
|
|
||||||
// gbm
|
// gbm
|
||||||
struct gbm_device *gbm;
|
struct gbm_device *gbm;
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
#include "screencast.h"
|
#include "screencast.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <drm_fourcc.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <spa/utils/result.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <drm_fourcc.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/mman.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 "pipewire_screencast.h"
|
||||||
#include "wlr_screencast.h"
|
#include "wlr_screencast.h"
|
||||||
#include "xdpw.h"
|
#include "xdpw.h"
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
static const char object_path[] = "/org/freedesktop/portal/desktop";
|
static const char object_path[] = "/org/freedesktop/portal/desktop";
|
||||||
static const char interface_name[] = "org.freedesktop.impl.portal.ScreenCast";
|
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,
|
void xdpw_screencast_instance_init(struct xdpw_screencast_context *ctx,
|
||||||
struct xdpw_screencast_instance *cast, struct xdpw_share out, bool with_cursor) {
|
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
|
// only run exec_before if there's no other instance running that already ran it
|
||||||
if (wl_list_empty(&ctx->screencast_instances)) {
|
if (wl_list_empty(&ctx->screencast_instances)) {
|
||||||
char *exec_before = ctx->state->config->screencast_conf.exec_before;
|
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
|
cast->max_framerate = 60; // dirty
|
||||||
} else {
|
} else {
|
||||||
if (ctx->state->config->screencast_conf.max_fps > 0) {
|
if (ctx->state->config->screencast_conf.max_fps > 0) {
|
||||||
cast->max_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;
|
||||||
ctx->state->config->screencast_conf.max_fps : (uint32_t)out.output->framerate;
|
|
||||||
} else {
|
} else {
|
||||||
cast->max_framerate = (uint32_t)out.output->framerate;
|
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) {
|
bool setup_outputs(struct xdpw_screencast_context *ctx, struct xdpw_session *sess, bool with_cursor) {
|
||||||
|
|
||||||
struct xdpw_wlr_output *output, *tmp_o;
|
struct xdpw_wlr_output *output, *tmp_o;
|
||||||
wl_list_for_each_reverse_safe(output, tmp_o, &ctx->output_list, link) {
|
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",
|
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);
|
logprint(INFO, "hyprland: window handle %d", sess->screencast_instance->target.window_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int start_screencast(struct xdpw_screencast_instance *cast) {
|
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
|
// process at least one frame so that we know
|
||||||
// some of the metadata required for the pipewire
|
// some of the metadata required for the pipewire
|
||||||
// remote state connected event
|
// remote state connected event
|
||||||
|
cast->ctx->toplevel_mgr_bind = 1;
|
||||||
wl_display_dispatch(cast->ctx->state->wl_display);
|
wl_display_dispatch(cast->ctx->state->wl_display);
|
||||||
wl_display_roundtrip(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) {
|
} else if (strcmp(key, "types") == 0) {
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
sd_bus_message_read(msg, "v", "u", &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");
|
logprint(INFO, "dbus: non-monitor cast requested, not replying");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -518,15 +514,15 @@ static const sd_bus_vtable screencast_vtable[] = {
|
||||||
SD_BUS_PROPERTY("version", "u", NULL,
|
SD_BUS_PROPERTY("version", "u", NULL,
|
||||||
offsetof(struct xdpw_state, screencast_version),
|
offsetof(struct xdpw_state, screencast_version),
|
||||||
SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_VTABLE_END
|
SD_BUS_VTABLE_END};
|
||||||
};
|
|
||||||
|
|
||||||
int xdpw_screencast_init(struct xdpw_state *state) {
|
int xdpw_screencast_init(struct xdpw_state *state) {
|
||||||
sd_bus_slot *slot = NULL;
|
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.state = state;
|
||||||
state->screencast.hyprland_toplevel_manager = NULL;
|
state->screencast.hyprland_toplevel_manager = NULL;
|
||||||
|
state->screencast.toplevel_mgr_bind = 0;
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
err = xdpw_pwr_context_create(state);
|
err = xdpw_pwr_context_create(state);
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
#include "wlr_screencast.h"
|
#include "wlr_screencast.h"
|
||||||
|
|
||||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
#include <assert.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 <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -15,16 +11,19 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
|
||||||
#include <wayland-client-protocol.h>
|
#include <wayland-client-protocol.h>
|
||||||
#include <xf86drm.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 "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 {
|
struct SToplevelEntry {
|
||||||
|
@ -58,6 +57,8 @@ void handleAppID(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, con
|
||||||
break;
|
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) {
|
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);
|
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) {
|
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 xdpw_screencast_context *ctx = data;
|
||||||
|
|
||||||
struct SToplevelEntry* entry = malloc(sizeof(struct SToplevelEntry));
|
struct SToplevelEntry *entry = malloc(sizeof(struct SToplevelEntry));
|
||||||
|
|
||||||
entry->handle = toplevel;
|
entry->handle = toplevel;
|
||||||
|
|
||||||
wl_list_insert(&ctx->toplevel_resource_list, &entry->link);
|
wl_list_insert(&ctx->toplevel_resource_list, &entry->link);
|
||||||
|
|
||||||
zwlr_foreign_toplevel_handle_v1_add_listener(toplevel, &toplevelHandleListener, ctx);
|
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) {
|
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 = {
|
struct zwlr_foreign_toplevel_manager_v1_listener toplevelListener = {
|
||||||
|
@ -125,7 +130,7 @@ struct zwlr_foreign_toplevel_manager_v1_listener toplevelListener = {
|
||||||
.finished = handleFinished,
|
.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;
|
struct SToplevelEntry *current;
|
||||||
wl_list_for_each(current, &ctx->toplevel_resource_list, link) {
|
wl_list_for_each(current, &ctx->toplevel_resource_list, link) {
|
||||||
if (((uint64_t)current->handle & 0xFFFFFFFF) == id) {
|
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);
|
uint64_t delay_ns = fps_limit_measure_end(&cast->fps_limit, cast->framerate);
|
||||||
if (delay_ns > 0) {
|
if (delay_ns > 0) {
|
||||||
xdpw_add_timer(cast->ctx->state, delay_ns,
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,7 +282,7 @@ static void wlr_frame_buffer_done(void *data,
|
||||||
assert(cast->current_frame.xdpw_buffer);
|
assert(cast->current_frame.xdpw_buffer);
|
||||||
|
|
||||||
// Check if dequeued buffer is compatible with announced 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->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->stride[0] != cast->screencopy_frame_info[cast->buffer_type].stride)) ||
|
||||||
cast->current_frame.xdpw_buffer->width != cast->screencopy_frame_info[cast->buffer_type].width ||
|
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_sec = ((((uint64_t)tv_sec_hi) << 32) | tv_sec_lo);
|
||||||
cast->current_frame.tv_nsec = tv_nsec;
|
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;
|
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);
|
assert(cast->current_frame.xdpw_buffer);
|
||||||
|
|
||||||
// Check if dequeued buffer is compatible with announced 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->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->stride[0] != cast->screencopy_frame_info[cast->buffer_type].stride)) ||
|
||||||
cast->current_frame.xdpw_buffer->width != cast->screencopy_frame_info[cast->buffer_type].width ||
|
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_sec = ((((uint64_t)tv_sec_hi) << 32) | tv_sec_lo);
|
||||||
cast->current_frame.tv_nsec = tv_nsec;
|
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;
|
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,
|
.flags = hyprland_frame_flags,
|
||||||
.ready = hyprland_frame_ready,
|
.ready = hyprland_frame_ready,
|
||||||
.failed = hyprland_frame_failed,
|
.failed = hyprland_frame_failed,
|
||||||
.damage = hyprland_frame_damage
|
.damage = hyprland_frame_damage};
|
||||||
};
|
|
||||||
|
|
||||||
void xdpw_wlr_register_cb(struct xdpw_screencast_instance *cast) {
|
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) {
|
if (cast->target.x != -1 && cast->target.y != -1 && cast->target.w != -1 && cast->target.h != -1 && cast->target.window_handle == -1) {
|
||||||
// capture region
|
// capture region
|
||||||
cast->frame_callback = zwlr_screencopy_manager_v1_capture_output_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);
|
cast->ctx->screencopy_manager, cast->with_cursor, cast->target.output->output);
|
||||||
} else {
|
} else {
|
||||||
// share window
|
// share window
|
||||||
struct SToplevelEntry* entry = toplevelEntryFromID(cast->ctx, cast->target.window_handle);
|
struct SToplevelEntry *entry = toplevelEntryFromID(cast->ctx, cast->target.window_handle);
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
logprint(DEBUG, "hyprland: error in getting 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) {
|
uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
|
||||||
if (flags & WL_OUTPUT_MODE_CURRENT) {
|
if (flags & WL_OUTPUT_MODE_CURRENT) {
|
||||||
struct xdpw_wlr_output *output = data;
|
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;
|
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) {
|
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);
|
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 *XCURSOR_SIZE = getenv("XCURSOR_SIZE");
|
||||||
const char *HYPRLAND_INSTANCE_SIGNATURE = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
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);
|
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
|
// find output
|
||||||
logprint(DEBUG, "Screencast: Attempting to find screen for %s", result);
|
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);
|
strncpy(display_name, result + 7, strlen(result) - 8);
|
||||||
display_name[strlen(result) - 8] = 0;
|
display_name[strlen(result) - 8] = 0;
|
||||||
|
|
||||||
struct xdpw_wlr_output* out;
|
struct xdpw_wlr_output *out;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
wl_list_for_each(out, &ctx->output_list, link) {
|
wl_list_for_each(out, &ctx->output_list, link) {
|
||||||
if (strcmp(out->name, display_name) == 0) {
|
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;
|
int atPos = 7;
|
||||||
for (int i = 7; i < (int)strlen(result); ++i) {
|
for (int i = 7; i < (int)strlen(result); ++i) {
|
||||||
if (result[i] == '@'){
|
if (result[i] == '@') {
|
||||||
atPos = i;
|
atPos = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -780,7 +781,7 @@ struct xdpw_share xdpw_wlr_chooser(struct xdpw_screencast_context *ctx) {
|
||||||
int coordbegin = 7 + strlen(display_name) + 1;
|
int coordbegin = 7 + strlen(display_name) + 1;
|
||||||
for (int i = 7 + strlen(display_name) + 1; i < (int)strlen(result); ++i) {
|
for (int i = 7 + strlen(display_name) + 1; i < (int)strlen(result); ++i) {
|
||||||
if (result[i] == ',' || result[i] == '@' || i + 1 == (int)strlen(result)) {
|
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);
|
strncpy(entire, result + coordbegin, i - coordbegin);
|
||||||
entire[i - coordbegin] = 0;
|
entire[i - coordbegin] = 0;
|
||||||
coords[coordno] = strtol(entire, NULL, 10);
|
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_release(&ctx->format_modifier_pairs);
|
||||||
wl_array_init(&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) {
|
if (ctx->feedback_data.format_table_data == MAP_FAILED) {
|
||||||
ctx->feedback_data.format_table_data = NULL;
|
ctx->feedback_data.format_table_data = NULL;
|
||||||
ctx->feedback_data.format_table_size = 0;
|
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
|
// An entry in the table has to be 16 bytes long
|
||||||
assert(sizeof(struct fm_entry) == 16);
|
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;
|
struct fm_entry *fm_entry = ctx->feedback_data.format_table_data;
|
||||||
uint16_t *idx;
|
uint16_t *idx;
|
||||||
wl_array_for_each(idx, indices) {
|
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) {
|
uint32_t id, const char *interface, uint32_t ver) {
|
||||||
struct xdpw_screencast_context *ctx = data;
|
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)) {
|
if (!strcmp(interface, wl_output_interface.name)) {
|
||||||
struct xdpw_wlr_output *output = calloc(1, sizeof(*output));
|
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);
|
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;
|
uint32_t version = ver;
|
||||||
|
|
||||||
logprint(DEBUG, "hyprland: |-- registered to interface %s (Version %u)", interface, version);
|
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);
|
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;
|
uint32_t version = ver;
|
||||||
|
|
||||||
logprint(DEBUG, "hyprland: |-- registered to interface %s (Version %u)", interface, version);
|
logprint(DEBUG, "hyprland: |-- registered to interface %s (Version %u)", interface, version);
|
||||||
|
|
Loading…
Reference in a new issue