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" />*
Add virtual output (headless backend).
Virtual outputs is a useful mechanism. For example, it can be used to overlay
virtual output on real output, but with a different resolution (this can be
done with `wlr-randr` or `wdisplays`). After that, virtual output can be
selected for screen sharing (casting), effectively sharing only the region of
the screen.
For example, it can be used to overlay virtual output on real output, but with
a different resolution (this can be done with `wlr-randr` or `wdisplays`).
After that, virtual output can be selected for screen sharing (casting),
effectively sharing only the region of the screen.
It must be noted that overlaying virtual output and real output is not
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
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
systems like tablets. E.g. simply adding a virtual output, attaching wayvnc to
it and running a VNC client on the remote system.
Virtual output is also useful for extending the desktop to (maybe mobile)
remote systems like tablets. E.g. simply adding a virtual output, attaching
wayvnc to it and running a VNC client on the remote system.
*output_name* The name of virtual output. Providing virtual output name is
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);
void handle_output_power_manager_set_mode(struct wl_listener *listener,
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_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
actions_run(struct view *activator, struct server *server,
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') {
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;
}
}
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;
}
}
}
}