Skip to content
This repository has been archived by the owner on Nov 1, 2021. It is now read-only.

Add relative outputs to wlr_output_layout #1002

Closed
wants to merge 12 commits into from
14 changes: 13 additions & 1 deletion include/rootston/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ struct roots_output_config {
char *name;
bool enable;
enum wl_output_transform transform;
int x, y;
float scale;
struct wl_list link;
struct {
Expand All @@ -19,6 +18,18 @@ struct roots_output_config {
} mode;
};

struct roots_layout_config {
struct wl_list rules;
};

struct roots_layout_rule_config {
char *output_name;
struct wl_list link;
enum wlr_output_layout_output_configuration configuration;
char *reference_output;
int x, y;
};

struct roots_device_config {
char *name;
char *seat;
Expand Down Expand Up @@ -68,6 +79,7 @@ struct roots_config {
struct wl_list keyboards;
struct wl_list cursors;

struct roots_layout_config layout;
char *config_path;
char *startup_cmd;
bool debug_damage_tracking;
Expand Down
3 changes: 2 additions & 1 deletion include/rootston/desktop.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "rootston/config.h"
#include "rootston/output.h"
#include "rootston/view.h"
#include "rootston/layout.h"

struct roots_desktop {
struct wl_list views; // roots_view::link
Expand All @@ -35,8 +36,8 @@ struct roots_desktop {

struct roots_server *server;
struct roots_config *config;
struct roots_layout *layout;

struct wlr_output_layout *layout;
struct wlr_xcursor_manager *xcursor_manager;

struct wlr_compositor *compositor;
Expand Down
29 changes: 29 additions & 0 deletions include/rootston/layout.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef ROOTSTON_LAYOUT_H
#define ROOTSTON_LAYOUT_H

#include <wlr/types/wlr_output_layout.h>
#include "rootston/config.h"
#include "rootston/output.h"

struct roots_layout_rule {
struct roots_layout_rule_config *config;
struct roots_output *output;
struct wl_list link;
bool configured;
};

struct roots_layout {
struct wlr_output_layout *wlr_layout;
struct roots_layout_config *current_config;
struct wl_list rules;
};

struct roots_layout* roots_layout_create(struct roots_layout_config *config);
void roots_layout_destroy(struct roots_layout *layout);
void roots_layout_add_output(struct roots_layout *layout,
struct roots_output *output);
void roots_layout_remove_output(struct roots_layout *layout,
struct roots_output *output);
void roots_layout_reflow(struct roots_layout *layout);

#endif
40 changes: 33 additions & 7 deletions include/wlr/types/wlr_output_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,24 @@ struct wlr_output_layout {

struct wlr_output_layout_output_state;

enum wlr_output_layout_output_configuration {
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_FIXED,
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_AUTO,
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_LEFT_OF,
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_RIGHT_OF,
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_BELOW,
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_ABOVE,
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_SAME_AS,
};

struct wlr_output_layout_output {
struct wlr_output *output;
int x, y;
enum wlr_output_layout_output_configuration configuration;
struct wlr_output_layout_output *reference;

struct wl_list link;

struct wlr_output_layout_output_state *state;

struct {
Expand Down Expand Up @@ -88,16 +102,28 @@ struct wlr_box *wlr_output_layout_get_box(
struct wlr_output_layout *layout, struct wlr_output *reference);

/**
* Add an auto configured output to the layout. This will place the output in a
* sensible location in the layout. The coordinates of the output in the layout
* may adjust dynamically when the layout changes. If the output is already in
* the layout, it will become auto configured. If the position of the output is
* set such as with `wlr_output_layout_move()`, the output will become manually
* configured.
*/
* Add an auto configured output to the layout. This will place the output in a
* sensible location in the layout. The coordinates of the output in the layout
* may adjust dynamically when the layout changes. If the output is already in
* the layout, it will become auto configured. Relative layouts are not supported
* with this kind of output.
*/
void wlr_output_layout_add_auto(struct wlr_output_layout *layout,
struct wlr_output *output);


/**
* Add an auto configured output to the layout relative to another output.
* This will place the relative output next to the border of the reference
* output. The output layout will adjust dynamically to keep the relative
* output in this position when the absolute output changes coordinates.
* If the position of the relative output is set to absolute coordinates,
* it will become manually configured.
*/
void wlr_output_layout_add_relative(struct wlr_output_layout *layout,
struct wlr_output *output, struct wlr_output *reference,
enum wlr_output_layout_output_configuration configuration);

/**
* Get the output closest to the center of the layout extents.
*/
Expand Down
97 changes: 93 additions & 4 deletions rootston/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,89 @@ static void config_handle_keyboard(struct roots_config *config,
}
}

static void config_handle_layout(struct roots_config *config, const char *name,
const char *value) {
struct roots_layout_config *lc = &config->layout;

char *mod_value = strdup(value);
char *strstart = mod_value;
char *saveptr;
mod_value = strtok_r(mod_value, " ", &saveptr);

struct roots_layout_rule_config *rule =
calloc(1, sizeof(struct roots_layout_rule_config));

if (strcmp(mod_value, "fixed") == 0) {
mod_value = strtok_r(NULL, ",", &saveptr);
if (!mod_value) {
goto invalid_config;
}
rule->x = strtol(mod_value, NULL, 10);
mod_value = strtok_r(NULL, " ", &saveptr);
if (!mod_value) {
goto invalid_config;
}
rule->y = strtol(mod_value, NULL, 10);
rule->configuration =
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_FIXED;

} else if (strcmp(mod_value, "left-of") == 0) {
mod_value = strtok_r(NULL, " ", &saveptr);
if (!mod_value) {
goto invalid_config;
}
rule->reference_output = strdup(mod_value);
rule->configuration =
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_LEFT_OF;
} else if (strcmp(mod_value, "right-of") == 0) {
mod_value = strtok_r(NULL, " ", &saveptr);
if (!mod_value) {
goto invalid_config;
}
rule->reference_output = strdup(mod_value);
rule->configuration =
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_RIGHT_OF;
} else if (strcmp(mod_value, "below") == 0) {
mod_value = strtok_r(NULL, " ", &saveptr);
if (!mod_value) {
goto invalid_config;
}
rule->reference_output = strdup(mod_value);
rule->configuration =
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_BELOW;
} else if (strcmp(mod_value, "above") == 0) {
mod_value = strtok_r(NULL, " ", &saveptr);
if (!mod_value) {
goto invalid_config;
}
rule->reference_output = strdup(mod_value);
rule->configuration =
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_ABOVE;
} else if (strcmp(mod_value, "same-as") == 0) {
mod_value = strtok_r(NULL, " ", &saveptr);
if (!mod_value) {
goto invalid_config;
}
rule->reference_output = strdup(mod_value);
rule->configuration =
WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_SAME_AS;
} else {
goto invalid_config;
}

rule->output_name = strdup(name);
wl_list_insert(&lc->rules, &rule->link);

free(strstart);

return;

invalid_config:
wlr_log(L_ERROR, "got invalid config for layout: %s = %s", name, value);
free(strstart);
free(rule);
}

static const char *output_prefix = "output:";
static const char *device_prefix = "device:";
static const char *keyboard_prefix = "keyboard:";
Expand Down Expand Up @@ -280,10 +363,6 @@ static int config_ini_handler(void *user, const char *section, const char *name,
} else {
wlr_log(L_ERROR, "got invalid output enable value: %s", value);
}
} else if (strcmp(name, "x") == 0) {
oc->x = strtol(value, NULL, 10);
} else if (strcmp(name, "y") == 0) {
oc->y = strtol(value, NULL, 10);
} else if (strcmp(name, "scale") == 0) {
oc->scale = strtof(value, NULL);
assert(oc->scale > 0);
Expand Down Expand Up @@ -376,6 +455,8 @@ static int config_ini_handler(void *user, const char *section, const char *name,
section, strlen(keyboard_prefix)) == 0) {
const char *device_name = section + strlen(keyboard_prefix);
config_handle_keyboard(config, device_name, name, value);
} else if (strcmp(section, "layout") == 0) {
config_handle_layout(config, name, value);
} else if (strcmp(section, "bindings") == 0) {
add_binding_config(&config->bindings, name, value);
} else {
Expand All @@ -398,6 +479,7 @@ struct roots_config *roots_config_create_from_args(int argc, char *argv[]) {
wl_list_init(&config->keyboards);
wl_list_init(&config->cursors);
wl_list_init(&config->bindings);
wl_list_init(&config->layout.rules);

int c;
while ((c = getopt(argc, argv, "C:E:hD")) != -1) {
Expand Down Expand Up @@ -500,6 +582,13 @@ void roots_config_destroy(struct roots_config *config) {
free(bc);
}

struct roots_layout_rule_config *lrc, *lrtmp = NULL;
wl_list_for_each_safe(lrc, lrtmp, &config->layout.rules, link) {
free(lrc->output_name);
free(lrc->reference_output);
free(lrc);
}

free(config->config_path);
free(config);
}
Expand Down
Loading