mirror of
https://cagebreak.project-repo.co/cagebreak.git
synced 2026-08-22 05:24:22 +02:00
Add support for disabling outputs
This commit is contained in:
parent
90475c24cb
commit
b2193f4c1d
7 changed files with 103 additions and 37 deletions
|
|
@ -335,6 +335,7 @@ main(int argc, char *argv[]) {
|
|||
|
||||
server.bg_color = (float[4]){0, 0, 0, 1};
|
||||
wl_list_init(&server.outputs);
|
||||
wl_list_init(&server.disabled_outputs);
|
||||
|
||||
server.output_layout = wlr_output_layout_create();
|
||||
if(!server.output_layout) {
|
||||
|
|
@ -544,8 +545,9 @@ main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
{
|
||||
struct cg_output *output;
|
||||
wl_list_for_each(output, &server.outputs, link) {
|
||||
|
||||
struct cg_output *output, *output_tmp;
|
||||
wl_list_for_each_safe(output, output_tmp, &server.outputs, link) {
|
||||
output_configure(&server, output);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
14
keybinding.c
14
keybinding.c
|
|
@ -838,6 +838,20 @@ keybinding_configure_output(struct cg_server *server,
|
|||
}
|
||||
}
|
||||
wl_list_insert(&server->output_config, &cfg->link);
|
||||
|
||||
struct cg_output *output, *tmp_output;
|
||||
wl_list_for_each_safe(output, tmp_output, &server->outputs, link) {
|
||||
if(strcmp(cfg->output_name, output->wlr_output->name) == 0) {
|
||||
output_configure(server, output);
|
||||
return;
|
||||
}
|
||||
}
|
||||
wl_list_for_each_safe(output, tmp_output, &server->disabled_outputs, link) {
|
||||
if(strcmp(cfg->output_name, output->wlr_output->name) == 0) {
|
||||
output_configure(server, output);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Hint: see keybinding.h for details on "data" */
|
||||
|
|
|
|||
80
output.c
80
output.c
|
|
@ -364,7 +364,7 @@ static void
|
|||
handle_output_transform(struct wl_listener *listener, void *data) {
|
||||
struct cg_output *output = wl_container_of(listener, output, transform);
|
||||
|
||||
if(!output->wlr_output->enabled) {
|
||||
if(!output->wlr_output->enabled || output->workspaces==NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -379,7 +379,7 @@ static void
|
|||
handle_output_mode(struct wl_listener *listener, void *data) {
|
||||
struct cg_output *output = wl_container_of(listener, output, mode);
|
||||
|
||||
if(!output->wlr_output->enabled) {
|
||||
if(!output->wlr_output->enabled || output->workspaces==NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -390,22 +390,15 @@ handle_output_mode(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
output_destroy(struct cg_output *output) {
|
||||
struct cg_server *server = output->server;
|
||||
|
||||
wl_list_remove(&output->destroy.link);
|
||||
wl_list_remove(&output->mode.link);
|
||||
wl_list_remove(&output->transform.link);
|
||||
wl_list_remove(&output->damage_frame.link);
|
||||
wl_list_remove(&output->damage_destroy.link);
|
||||
|
||||
void output_clear(struct cg_output* output) {
|
||||
struct cg_server *server=output->server;
|
||||
wlr_output_layout_remove(server->output_layout, output->wlr_output);
|
||||
|
||||
if(server->running && server->curr_output == output &&
|
||||
wl_list_length(&server->outputs) > 1) {
|
||||
keybinding_cycle_outputs(server, false);
|
||||
}
|
||||
|
||||
wl_list_remove(&output->link);
|
||||
|
||||
message_clear(output);
|
||||
|
|
@ -413,6 +406,13 @@ output_destroy(struct cg_output *output) {
|
|||
struct cg_view *view, *view_tmp;
|
||||
if(server->running) {
|
||||
for(unsigned int i = 0; i < server->nws; ++i) {
|
||||
|
||||
bool first = true;
|
||||
for(struct cg_tile *tile = output->workspaces[i]->focused_tile;
|
||||
first || output->workspaces[i]->focused_tile != tile; tile = tile->next) {
|
||||
first = false;
|
||||
tile->view=NULL;
|
||||
}
|
||||
wl_list_for_each_safe(view, view_tmp, &output->workspaces[i]->views,
|
||||
link) {
|
||||
wl_list_remove(&view->link);
|
||||
|
|
@ -451,6 +451,20 @@ output_destroy(struct cg_output *output) {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
output_destroy(struct cg_output *output) {
|
||||
struct cg_server *server = output->server;
|
||||
|
||||
wl_list_remove(&output->destroy.link);
|
||||
wl_list_remove(&output->mode.link);
|
||||
wl_list_remove(&output->transform.link);
|
||||
wl_list_remove(&output->damage_frame.link);
|
||||
wl_list_remove(&output->damage_destroy.link);
|
||||
|
||||
output_clear(output);
|
||||
|
||||
/*Important: due to unfortunate events, "workspace" and "output->workspace"
|
||||
* have nothing in common. The former is the workspace of a single output,
|
||||
* whereas the latter is the workspace of the outputs.*/
|
||||
|
|
@ -530,11 +544,15 @@ void
|
|||
output_configure(struct cg_server *server, struct cg_output *output) {
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
struct cg_output_config *config = output_find_config(server, wlr_output);
|
||||
/* Refuse to disable the only output */
|
||||
if(config!=NULL&&config->status == OUTPUT_DISABLE && wl_list_length(&server->outputs)==1) {
|
||||
return;
|
||||
}
|
||||
if(output->wlr_output->enabled) {
|
||||
wlr_output_layout_remove(server->output_layout, wlr_output);
|
||||
}
|
||||
|
||||
if(config == NULL) {
|
||||
if(config == NULL || config->status == OUTPUT_ENABLE) {
|
||||
wlr_output_layout_add_auto(server->output_layout, wlr_output);
|
||||
|
||||
struct wlr_output_mode *preferred_mode =
|
||||
|
|
@ -542,11 +560,24 @@ output_configure(struct cg_server *server, struct cg_output *output) {
|
|||
if(preferred_mode) {
|
||||
wlr_output_set_mode(wlr_output, preferred_mode);
|
||||
}
|
||||
wl_list_remove(&output->link);
|
||||
wl_list_insert(&server->outputs,&output->link);
|
||||
wlr_output_enable(wlr_output, true);
|
||||
wlr_output_commit(wlr_output);
|
||||
} else if(config->status == OUTPUT_DISABLE) {
|
||||
output_clear(output);
|
||||
wl_list_insert(&server->disabled_outputs,&output->link);
|
||||
wlr_output_enable(wlr_output, false);
|
||||
wlr_output_commit(wlr_output);
|
||||
} else {
|
||||
wl_list_remove(&output->link);
|
||||
wl_list_insert(&server->outputs,&output->link);
|
||||
output_set_mode(wlr_output, config->pos.width, config->pos.height,
|
||||
config->refresh_rate);
|
||||
wlr_output_layout_add(server->output_layout, wlr_output, config->pos.x,
|
||||
config->pos.y);
|
||||
wlr_output_enable(wlr_output, true);
|
||||
wlr_output_commit(wlr_output);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -569,7 +600,6 @@ handle_new_output(struct wl_listener *listener, void *data) {
|
|||
output->server = server;
|
||||
output->damage = wlr_output_damage_create(wlr_output);
|
||||
output->last_scanned_out_view = NULL;
|
||||
wl_list_insert(&server->outputs, &output->link);
|
||||
|
||||
output->mode.notify = handle_output_mode;
|
||||
wl_signal_add(&wlr_output->events.mode, &output->mode);
|
||||
|
|
@ -583,19 +613,7 @@ handle_new_output(struct wl_listener *listener, void *data) {
|
|||
wl_signal_add(&output->damage->events.destroy, &output->damage_destroy);
|
||||
|
||||
wlr_output_set_transform(wlr_output, server->output_transform);
|
||||
|
||||
output_configure(server, output);
|
||||
|
||||
output->workspaces = malloc(server->nws * sizeof(struct cg_workspace *));
|
||||
for(unsigned int i = 0; i < server->nws; ++i) {
|
||||
output->workspaces[i] = full_screen_workspace(output);
|
||||
if(!output->workspaces[i]) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate workspaces for output");
|
||||
return;
|
||||
}
|
||||
wl_list_init(&output->workspaces[i]->views);
|
||||
wl_list_init(&output->workspaces[i]->unmanaged_views);
|
||||
}
|
||||
output->workspaces=NULL;
|
||||
|
||||
output->curr_workspace = 0;
|
||||
wl_list_init(&output->messages);
|
||||
|
|
@ -607,14 +625,12 @@ handle_new_output(struct wl_listener *listener, void *data) {
|
|||
wlr_output->name, wlr_output->scale);
|
||||
}
|
||||
|
||||
wl_list_insert(&server->outputs, &output->link);
|
||||
output_configure(server, output);
|
||||
wlr_output_damage_add_whole(output->damage);
|
||||
|
||||
wlr_output_enable(wlr_output, true);
|
||||
wlr_output_commit(wlr_output);
|
||||
|
||||
/* TODO:If you see a way to circumvent having to loop twice, please do so */
|
||||
output->workspaces = malloc(server->nws * sizeof(struct cg_workspace *));
|
||||
for(unsigned int i = 0; i < server->nws; ++i) {
|
||||
workspace_free(output->workspaces[i]);
|
||||
output->workspaces[i] = full_screen_workspace(output);
|
||||
if(!output->workspaces[i]) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate workspaces for output");
|
||||
|
|
|
|||
7
output.h
7
output.h
|
|
@ -28,7 +28,14 @@ struct cg_output {
|
|||
struct wl_list link; // cg_server::outputs
|
||||
};
|
||||
|
||||
enum output_status {
|
||||
OUTPUT_ENABLE,
|
||||
OUTPUT_DISABLE,
|
||||
OUTPUT_DEFAULT
|
||||
};
|
||||
|
||||
struct cg_output_config {
|
||||
enum output_status status;
|
||||
struct wlr_box pos;
|
||||
char *output_name;
|
||||
float refresh_rate;
|
||||
|
|
|
|||
27
parse.c
27
parse.c
|
|
@ -259,6 +259,23 @@ parse_float(char **saveptr, const char *delim) {
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
parse_output_config_keyword(char *key_str,enum output_status *status) {
|
||||
if(key_str == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if(strcmp(key_str,"pos") == 0) {
|
||||
*status=OUTPUT_DEFAULT;
|
||||
} else if(strcmp(key_str, "enable") == 0) {
|
||||
*status=OUTPUT_ENABLE;
|
||||
} else if(strcmp(key_str, "disable") == 0) {
|
||||
*status=OUTPUT_DISABLE;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct cg_output_config *
|
||||
parse_output_config(char **saveptr, char **errstr) {
|
||||
struct cg_output_config *cfg = malloc(sizeof(struct cg_output_config));
|
||||
|
|
@ -273,13 +290,17 @@ parse_output_config(char **saveptr, char **errstr) {
|
|||
log_error("Expected name of output to be configured, got none");
|
||||
goto error;
|
||||
}
|
||||
char *pos_str = strtok_r(NULL, " ", saveptr);
|
||||
if(pos_str == NULL || strcmp(pos_str, "pos") != 0) {
|
||||
char *key_str = strtok_r(NULL, " ", saveptr);
|
||||
if(parse_output_config_keyword(key_str,&(cfg->status))!=0) {
|
||||
*errstr = log_error(
|
||||
"Expected keyword \"pos\" in output configuration for output %s",
|
||||
"Expected keyword \"pos\", \"enable\" or \"disable\" in output configuration for output %s",
|
||||
name);
|
||||
goto error;
|
||||
}
|
||||
if(cfg->status == OUTPUT_ENABLE || cfg->status == OUTPUT_DISABLE) {
|
||||
cfg->output_name = strdup(name);
|
||||
return cfg;
|
||||
}
|
||||
|
||||
cfg->pos.x = parse_uint(saveptr, " ");
|
||||
if(cfg->pos.x < 0) {
|
||||
|
|
|
|||
5
seat.c
5
seat.c
|
|
@ -54,6 +54,11 @@ view_at(const struct cg_view *view, double lx, double ly,
|
|||
struct wlr_surface **surface, double *sx, double *sy) {
|
||||
struct wlr_box *output_layout_box = wlr_output_layout_get_box(
|
||||
view->server->output_layout, view->workspace->output->wlr_output);
|
||||
if(output_layout_box == NULL) {
|
||||
fprintf(stderr, "OUTPUT:%d\n",view->workspace->output->wlr_output->enabled);
|
||||
return output_layout_box->x;
|
||||
return false;
|
||||
}
|
||||
|
||||
double view_sx = lx - view->ox - output_layout_box->x;
|
||||
double view_sy = ly - view->oy - output_layout_box->y;
|
||||
|
|
|
|||
1
server.h
1
server.h
|
|
@ -26,6 +26,7 @@ struct cg_server {
|
|||
struct wl_list inhibitors;
|
||||
|
||||
struct wlr_output_layout *output_layout;
|
||||
struct wl_list disabled_outputs;
|
||||
struct wl_list outputs;
|
||||
struct cg_output *curr_output;
|
||||
struct wl_listener new_output;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue