virtual outputs: address code review

This commit is contained in:
kyak 2023-12-08 05:28:32 +03:00
parent 0c37cd5e25
commit 9a41e91718
4 changed files with 62 additions and 60 deletions

View file

@ -183,11 +183,10 @@ Actions are used in menus and keyboard/mouse bindings.
*<action name="VirtualOutputAdd" output_name="value" />* *<action name="VirtualOutputAdd" output_name="value" />*
Add virtual output (headless backend). Add virtual output (headless backend).
Virtual outputs is a useful mechanism. For example, it can be used to overlay For example, it can be used to overlay virtual output on real output, but with
virtual output on real output, but with a different resolution (this can be a different resolution (this can be done with `wlr-randr` or `wdisplays`).
done with `wlr-randr` or `wdisplays`). After that, virtual output can be After that, virtual output can be selected for screen sharing (casting),
selected for screen sharing (casting), effectively sharing only the region of effectively sharing only the region of the screen.
the screen.
It must be noted that overlaying virtual output and real output is not It must be noted that overlaying virtual output and real output is not
endorsed or explicitely supported by wlroots. For example, after configuring endorsed or explicitely supported by wlroots. For example, after configuring
@ -207,9 +206,9 @@ Actions are used in menus and keyboard/mouse bindings.
Note that the vertical resolution of "ScreenCasting" output is just 50px Note that the vertical resolution of "ScreenCasting" output is just 50px
smaller than "eDP-1" output to cut off bottom panel from screen sharing. smaller than "eDP-1" output to cut off bottom panel from screen sharing.
This setup is also useful for extending the desktop to (maybe mobile) remote Virtual output is also useful for extending the desktop to (maybe mobile)
systems like tablets. E.g. simply adding a virtual output, attaching wayvnc to remote systems like tablets. E.g. simply adding a virtual output, attaching
it and running a VNC client on the remote system. wayvnc to it and running a VNC client on the remote system.
*output_name* The name of virtual output. Providing virtual output name is *output_name* The name of virtual output. Providing virtual output name is
beneficial for further automation. Default is "HEADLESS-X". beneficial for further automation. Default is "HEADLESS-X".

View file

@ -471,6 +471,8 @@ struct wlr_box output_usable_area_in_layout_coords(struct output *output);
struct wlr_box output_usable_area_scaled(struct output *output); struct wlr_box output_usable_area_scaled(struct output *output);
void handle_output_power_manager_set_mode(struct wl_listener *listener, void handle_output_power_manager_set_mode(struct wl_listener *listener,
void *data); void *data);
void virtual_output_add(struct server *server, const char *output_name);
void virtual_output_remove(struct server *server, const char *output_name);
void server_init(struct server *server); void server_init(struct server *server);
void server_start(struct server *server); void server_start(struct server *server);

View file

@ -629,58 +629,6 @@ run_if_action(struct view *view, struct server *server, struct action *action)
} }
} }
static void
virtual_output_add(struct server *server, const char *output_name)
{
if (output_name) {
/*
* Prevent creating outputs with the same name
*/
struct output *output;
wl_list_for_each(output, &server->outputs, link) {
if (wlr_output_is_headless(output->wlr_output)) {
if (!strcmp(output->wlr_output->name, output_name)) {
wlr_log(WLR_DEBUG,
"refusing to create virtual output with duplicate name");
return;
}
}
}
strncpy(server->headless.pending_output_name, output_name,
sizeof(server->headless.pending_output_name));
} else {
server->headless.pending_output_name[0] = '\0';
}
wlr_headless_add_output(server->headless.backend, 1920, 1080);
}
static void
virtual_output_remove(struct server *server, const char *output_name)
{
struct output *output;
wl_list_for_each(output, &server->outputs, link) {
if (wlr_output_is_headless(output->wlr_output)) {
if (output_name) {
/*
* Given virtual output name, find and destroy virtual output by
* that name.
*/
if (!strcmp(output->wlr_output->name, output_name)) {
wlr_output_destroy(output->wlr_output);
return;
}
} else {
/*
* When virtual output name was no supplied by user, simply
* destroy the first virtual output found.
*/
wlr_output_destroy(output->wlr_output);
return;
}
}
}
}
void void
actions_run(struct view *activator, struct server *server, actions_run(struct view *activator, struct server *server,
struct wl_list *actions, uint32_t resize_edges) struct wl_list *actions, uint32_t resize_edges)

View file

@ -201,6 +201,7 @@ new_output_notify(struct wl_listener *listener, void *data)
*/ */
if (wlr_output_is_headless(wlr_output) && server->headless.pending_output_name[0] != '\0') { if (wlr_output_is_headless(wlr_output) && server->headless.pending_output_name[0] != '\0') {
wlr_output_set_name(wlr_output, server->headless.pending_output_name); wlr_output_set_name(wlr_output, server->headless.pending_output_name);
server->headless.pending_output_name[0] = '\0';
} }
/* /*
@ -777,3 +778,55 @@ handle_output_power_manager_set_mode(struct wl_listener *listener, void *data)
break; break;
} }
} }
void
virtual_output_add(struct server *server, const char *output_name)
{
if (output_name) {
/*
* Prevent creating outputs with the same name
*/
struct output *output;
wl_list_for_each(output, &server->outputs, link) {
if (wlr_output_is_headless(output->wlr_output)) {
if (!strcmp(output->wlr_output->name, output_name)) {
wlr_log(WLR_DEBUG,
"refusing to create virtual output with duplicate name");
return;
}
}
}
strncpy(server->headless.pending_output_name, output_name,
sizeof(server->headless.pending_output_name));
} else {
server->headless.pending_output_name[0] = '\0';
}
wlr_headless_add_output(server->headless.backend, 1920, 1080);
}
void
virtual_output_remove(struct server *server, const char *output_name)
{
struct output *output;
wl_list_for_each(output, &server->outputs, link) {
if (wlr_output_is_headless(output->wlr_output)) {
if (output_name) {
/*
* Given virtual output name, find and destroy virtual output by
* that name.
*/
if (!strcmp(output->wlr_output->name, output_name)) {
wlr_output_destroy(output->wlr_output);
return;
}
} else {
/*
* When virtual output name was no supplied by user, simply
* destroy the first virtual output found.
*/
wlr_output_destroy(output->wlr_output);
return;
}
}
}
}