Tentative implementation of "permanent outputs"

This commit is contained in:
project-repo 2023-09-14 15:36:01 +02:00
commit 6b89645161
13 changed files with 233 additions and 168 deletions

View file

@ -249,8 +249,7 @@ swap_tile(struct cg_tile *tile,
"{\"event_name\":\"swap_tile\",\"tile_id\":%d,\"swap_"
"tile_id\":%d,\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}",
tile->id, swap_tile->id, tile->workspace->num + 1,
tile->workspace->output->wlr_output->name,
output_get_num(tile->workspace->output));
tile->workspace->output->name, output_get_num(tile->workspace->output));
}
void
@ -400,8 +399,7 @@ resize(struct cg_tile *tile, const struct cg_tile *parent, int coord_offset,
"\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}",
tile->id, old_x, old_y, old_height, old_width, tile->tile.x,
tile->tile.y, tile->tile.height, tile->tile.width,
tile->workspace->num + 1,
tile->workspace->output->wlr_output->name,
tile->workspace->num + 1, tile->workspace->output->name,
output_get_num(tile->workspace->output));
}
@ -456,18 +454,18 @@ resize_vertical(struct cg_tile *tile, struct cg_tile *parent, int y_offset,
void
resize_tile(struct cg_server *server, int hpixs, int vpixs) {
struct cg_output *output = server->curr_output;
struct wlr_box output_box;
wlr_output_layout_get_box(output->server->output_layout, output->wlr_output,
&output_box);
struct cg_tile *focused =
output->workspaces[output->curr_workspace]->focused_tile;
/* First do the horizontal adjustment */
if(hpixs != 0 && focused->tile.width < output_box.width &&
is_between_strict(0, output_box.width, focused->tile.width + hpixs)) {
if(hpixs != 0 &&
focused->tile.width < output_get_layout_box(output).width &&
is_between_strict(0, output_get_layout_box(output).width,
focused->tile.width + hpixs)) {
int x_offset = 0;
/* In case we are on the total right, move the left edge of the tile */
if(focused->tile.x + focused->tile.width == output_box.width) {
if(focused->tile.x + focused->tile.width ==
output_get_layout_box(output).width) {
x_offset = -hpixs;
}
bool resize_allowed =
@ -477,10 +475,13 @@ resize_tile(struct cg_server *server, int hpixs, int vpixs) {
}
}
/* Repeat for vertical */
if(vpixs != 0 && focused->tile.height < output_box.height &&
is_between_strict(0, output_box.height, focused->tile.height + vpixs)) {
if(vpixs != 0 &&
focused->tile.height < output_get_layout_box(output).height &&
is_between_strict(0, output_get_layout_box(output).height,
focused->tile.height + vpixs)) {
int y_offset = 0;
if(focused->tile.y + focused->tile.height == output_box.height) {
if(focused->tile.y + focused->tile.height ==
output_get_layout_box(output).height) {
y_offset = -vpixs;
}
bool resize_allowed =
@ -501,7 +502,7 @@ keybinding_workspace_fullscreen(struct cg_server *server) {
"\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}",
output->workspaces[output->curr_workspace]->focused_tile->id,
output->workspaces[output->curr_workspace]->num + 1,
output->wlr_output->name, output_get_num(output));
output->name, output_get_num(output));
}
// Switch to a differerent virtual terminal
@ -595,8 +596,8 @@ keybinding_split_output(struct cg_output *output, bool vertical) {
"{\"event_name\":\"split\",\"tile_id\":%d,\"new_tile_id\":%d,"
"\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d,\"vertical\":%d}",
curr_workspace->focused_tile->id, new_tile->id, curr_workspace->num + 1,
curr_workspace->output->wlr_output->name,
output_get_num(curr_workspace->output), vertical);
curr_workspace->output->name, output_get_num(curr_workspace->output),
vertical);
}
static void
@ -614,8 +615,7 @@ keybinding_close_view(struct cg_view *view) {
outp->server,
"{\"event_name\":\"close\",\"view_id\":%d,\"view_pid\":%d,\"tile_id\":"
"%d,\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}",
view_id, view_pid, tile_id, ws + 1, outp->wlr_output->name,
output_get_num(outp));
view_id, view_pid, tile_id, ws + 1, outp->name, output_get_num(outp));
}
static void
@ -670,8 +670,8 @@ keybinding_cycle_outputs(struct cg_server *server, bool reverse,
"{\"event_name\":\"cycle_outputs\",\"old_output\":\"%s\",\"old_"
"output_id\":%d,"
"\"new_output\":\"%s\",\"new_output_id\":%d,\"reverse\":%d}",
old_output->wlr_output->name, output_get_num(old_output),
output->wlr_output->name, output_get_num(output), reverse);
old_output->name, output_get_num(old_output), output->name,
output_get_num(output), reverse);
}
}
@ -721,7 +721,7 @@ keybinding_cycle_views(struct cg_server *server, bool reverse, bool ipc) {
curr_id, curr_pid, next_view == NULL ? -1 : (int)next_view->id,
next_view == NULL ? -1 : (int)next_view->impl->get_pid(next_view),
next_view->tile->id, curr_workspace->num + 1,
curr_workspace->output->wlr_output->name,
curr_workspace->output->name,
output_get_num(curr_workspace->output));
}
}
@ -744,7 +744,7 @@ keybinding_focus_tile(struct cg_server *server, uint32_t tile_id) {
"{\"event_name\":\"focus_tile\",\"old_tile_id\":%d,\"new_tile_"
"id\":%d,\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}",
old_tile->id, workspace->focused_tile->id, workspace->num + 1,
output->wlr_output->name, output_get_num(output));
output->name, output_get_num(output));
break;
}
}
@ -778,8 +778,7 @@ keybinding_switch_ws(struct cg_server *server, uint32_t ws) {
ipc_send_event(output->server,
"{\"event_name\":\"switch_ws\",\"old_workspace\":%d,"
"\"new_workspace\":%d,\"output\":\"%s\",\"output_id\":%d}",
old_ws + 1, ws + 1, output->wlr_output->name,
output_get_num(output));
old_ws + 1, ws + 1, output->name, output_get_num(output));
return 0;
}
@ -1020,14 +1019,11 @@ print_output(struct cg_output *outp) {
outp_str.len = 0;
outp_str.cur_pos = 0;
uint32_t nmemb = 8;
struct wlr_box outp_box;
wlr_output_layout_get_box(outp->server->output_layout, outp->wlr_output,
&outp_box);
outp_str.str_arr = calloc(nmemb, sizeof(char *));
print_str(&outp_str, "\"%s\": {\n", outp->wlr_output->name);
print_str(&outp_str, "\"%s\": {\n", outp->name);
print_str(&outp_str, "\"priority\": %d,\n", outp->priority);
print_str(&outp_str, "\"coords\": {\"x\":%d,\"y\":%d},\n", outp_box.x,
outp_box.y);
print_str(&outp_str, "\"coords\": {\"x\":%d,\"y\":%d},\n",
output_get_layout_box(outp).x, output_get_layout_box(outp).y);
print_str(&outp_str, "\"size\": {\"width\":%d,\"height\":%d},\n",
outp->wlr_output->width, outp->wlr_output->height);
print_str(&outp_str, "\"refresh_rate\": %f,\n",
@ -1202,8 +1198,7 @@ keybinding_dump(struct cg_server *server) {
}
print_str(&str, "\"views_curr_id\":%d,\n", curr_view_id);
print_str(&str, "\"tiles_curr_id\":%d,\n", curr_tile_id);
print_str(&str, "\"curr_output\":\"%s\",\n",
server->curr_output->wlr_output->name);
print_str(&str, "\"curr_output\":\"%s\",\n", server->curr_output->name);
print_str(&str, "\"default_mode\":\"%s\",\n",
get_mode_name(server->modes, server->seat->default_mode));
print_modes(&str, server->modes);
@ -1298,9 +1293,8 @@ keybinding_move_view_to_cycle_output(struct cg_server *server, bool reverse) {
"{\"event_name\":\"move_view_to_cycle_output\",\"view_id\":%d,\"view_"
"pid\":%d,\"old_output\":\"%s\",\"old_output_id\":%d,\"new_output\":\"%"
"s\",\"new_output_id\":%d,\"old_tile_id\":%d,\"new_tile_id\":%d}",
id, pid, old_outp->wlr_output->name, output_get_num(old_outp),
server->curr_output->wlr_output->name,
output_get_num(server->curr_output),
id, pid, old_outp->name, output_get_num(old_outp),
server->curr_output->name, output_get_num(server->curr_output),
old_outp->workspaces[old_outp->curr_workspace]->focused_tile->id,
server->curr_output->workspaces[server->curr_output->curr_workspace]
->focused_tile->id);
@ -1422,8 +1416,8 @@ keybinding_switch_output(struct cg_server *server, int output) {
"{\"event_name\":\"switch_output\",\"old_output\":"
"\"%s\",\"old_output_id\":%d,\"new_output\":\"%s\","
"\"new_output_id\":%d}",
old_outp->wlr_output->name, output_get_num(old_outp),
it->wlr_output->name, output_get_num(it));
old_outp->name, output_get_num(old_outp), it->name,
output_get_num(it));
return;
}
++count;
@ -1469,8 +1463,7 @@ keybinding_move_view_to_output(struct cg_server *server, int output_num) {
server,
"{\"event_name\":\"move_view_to_output\",\"view_id\":%d,\"old_"
"output\":\"%s\",\"new_output\":\"%s\"}",
view_id, old_outp->wlr_output->name,
server->curr_output->wlr_output->name);
view_id, old_outp->name, server->curr_output->name);
}
void
@ -1505,7 +1498,7 @@ keybinding_move_view_to_workspace(struct cg_server *server, uint32_t ws) {
"\"old_workspace\":%d,\"new_workspace\":%d,"
"\"output\":\"%s\",\"output_id\":%d,\"view_pid\":%d}",
view == NULL ? -1 : (int)view->id, old_ws + 1, ws + 1,
server->curr_output->wlr_output->name,
server->curr_output->name,
output_get_num(server->curr_output),
view == NULL ? 0 : view->impl->get_pid(view));
}
@ -1554,7 +1547,7 @@ keybinding_configure_output(struct cg_server *server,
struct cg_output *output, *tmp_output;
wl_list_for_each_safe(output, tmp_output, &server->outputs, link) {
if(strcmp(config->output_name, output->wlr_output->name) == 0) {
if(strcmp(config->output_name, output->name) == 0) {
output_configure(server, output);
ipc_send_event(output->server,
"{\"event_name\":\"configure_output\",\"output\":\"%"
@ -1564,7 +1557,7 @@ keybinding_configure_output(struct cg_server *server,
}
}
wl_list_for_each_safe(output, tmp_output, &server->disabled_outputs, link) {
if(strcmp(config->output_name, output->wlr_output->name) == 0) {
if(strcmp(config->output_name, output->name) == 0) {
output_configure(server, output);
ipc_send_event(
output->server,

View file

@ -219,7 +219,7 @@ output_by_name_or_id(const char *name_or_id, struct cg_server *server) {
char identifier[128];
output_get_identifier(identifier, sizeof(identifier), output);
if(strcasecmp(identifier, name_or_id) == 0 ||
strcasecmp(output->wlr_output->name, name_or_id) == 0) {
strcasecmp(output->name, name_or_id) == 0) {
return output;
}
}

View file

@ -236,17 +236,18 @@ message_set_output(struct cg_output *output, const char *string,
wlr_scene_buffer_create(&scene_output->scene->tree, &buf->base);
wlr_scene_node_raise_to_top(&message->message->node);
wlr_scene_node_set_enabled(&message->message->node, true);
struct wlr_box outp_box;
wlr_output_layout_get_box(output->server->output_layout, output->wlr_output,
&outp_box);
wlr_scene_buffer_set_dest_size(message->message, width, height);
wlr_scene_node_set_position(&message->message->node,
message->position->x + outp_box.x,
message->position->y + outp_box.y);
wlr_scene_node_set_position(
&message->message->node,
message->position->x + output_get_layout_box(output).x,
message->position->y + output_get_layout_box(output).y);
}
void
message_printf(struct cg_output *output, const char *fmt, ...) {
if(output->destroyed) {
return;
}
va_list ap;
va_start(ap, fmt);
char *buffer = malloc_vsprintf_va_list(fmt, ap);
@ -262,11 +263,7 @@ message_printf(struct cg_output *output, const char *fmt, ...) {
free(buffer);
return;
}
struct wlr_box output_box;
wlr_output_layout_get_box(output->server->output_layout, output->wlr_output,
&output_box);
box->x = output_box.width;
box->x = output_get_layout_box(output).width;
box->y = 0;
box->width = 0;
box->height = 0;
@ -282,6 +279,9 @@ message_printf(struct cg_output *output, const char *fmt, ...) {
void
message_printf_pos(struct cg_output *output, struct wlr_box *position,
const enum cg_message_align align, const char *fmt, ...) {
if(output->destroyed) {
return;
}
uint16_t buf_len = 256;
char *buffer = (char *)malloc(buf_len * sizeof(char));
va_list ap;

175
output.c
View file

@ -103,7 +103,7 @@ output_get_num(const struct cg_output *output) {
struct cg_output *it;
int count = 1;
wl_list_for_each(it, &output->server->outputs, link) {
if(strcmp(output->wlr_output->name, it->wlr_output->name) == 0) {
if(strcmp(output->name, it->name) == 0) {
return count;
}
++count;
@ -111,34 +111,47 @@ output_get_num(const struct cg_output *output) {
return -1;
}
struct wlr_box
output_get_layout_box(struct cg_output *output) {
if(!output->destroyed) {
wlr_output_layout_get_box(output->server->output_layout,
output->wlr_output, &output->layout_box);
}
return output->layout_box;
}
static void
output_destroy(struct cg_output *output) {
struct cg_server *server = output->server;
char *outp_name = strdup(output->wlr_output->name);
char *outp_name = strdup(output->name);
int outp_num = output_get_num(output);
output->destroyed = true;
wl_list_remove(&output->destroy.link);
wl_list_remove(&output->mode.link);
wl_list_remove(&output->commit.link);
wl_list_remove(&output->frame.link);
enum output_role role = output->role;
if(role == OUTPUT_ROLE_PERMANENT) {
wlr_output_layout_get_box(server->output_layout, output->wlr_output,
&output->layout_box);
} else {
output_clear(output);
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.*/
for(unsigned int i = 0; i < server->nws; ++i) {
workspace_free(output->workspaces[i]);
for(unsigned int i = 0; i < server->nws; ++i) {
workspace_free(output->workspaces[i]);
}
free(output->workspaces);
free(output->name);
free(output);
}
free(output->workspaces);
free(output);
if(outp_name != NULL) {
ipc_send_event(server,
"{\"event_name\":\"destroy_output\",\"output\":\"%s\","
"\"output_id\":%d}",
outp_name, outp_num);
"\"output_id\":%d,\"permanent\":%d}",
outp_name, outp_num, role == OUTPUT_ROLE_PERMANENT);
free(outp_name);
} else {
wlr_log(WLR_ERROR,
@ -258,6 +271,10 @@ output_apply_config(struct cg_server *server, struct cg_output *output,
struct cg_output_config *config) {
struct wlr_output *wlr_output = output->wlr_output;
if(config->role != OUTPUT_ROLE_DEFAULT) {
output->role = config->role;
}
if(output->wlr_output->enabled) {
wlr_output_layout_remove(server->output_layout, wlr_output);
}
@ -325,9 +342,11 @@ output_apply_config(struct cg_server *server, struct cg_output *output,
output->bg = wlr_scene_rect_create(
&scene_output->scene->tree, output->wlr_output->width,
output->wlr_output->height, server->bg_color);
struct wlr_box box;
wlr_output_layout_get_box(server->output_layout, output->wlr_output, &box);
wlr_scene_node_set_position(&output->bg->node, box.x, box.y);
wlr_output_layout_get_box(server->output_layout, output->wlr_output,
&output->layout_box);
wlr_scene_node_set_position(&output->bg->node,
output_get_layout_box(output).x,
output_get_layout_box(output).y);
wlr_scene_node_lower_to_bottom(&output->bg->node);
}
@ -340,6 +359,7 @@ empty_output_config(void) {
}
cfg->status = OUTPUT_DEFAULT;
cfg->role = OUTPUT_ROLE_DEFAULT;
cfg->pos.x = -1;
cfg->pos.y = -1;
cfg->pos.width = -1;
@ -363,6 +383,11 @@ merge_output_configs(struct cg_output_config *cfg1,
} else {
out_cfg->status = cfg1->status;
}
if(cfg1->role == out_cfg->role) {
out_cfg->role = cfg2->role;
} else {
out_cfg->role = cfg1->role;
}
if(cfg1->pos.x == out_cfg->pos.x) {
out_cfg->pos.x = cfg2->pos.x;
out_cfg->pos.y = cfg2->pos.y;
@ -411,7 +436,7 @@ output_configure(struct cg_server *server, struct cg_output *output) {
struct cg_output_config *tot_config = empty_output_config();
struct cg_output_config *config;
wl_list_for_each(config, &server->output_config, link) {
if(strcmp(config->output_name, output->wlr_output->name) == 0) {
if(strcmp(config->output_name, output->name) == 0) {
if(tot_config == NULL) {
return;
}
@ -484,7 +509,7 @@ output_make_workspace_fullscreen(struct cg_output *output, int ws) {
}
workspace_free_tiles(output->workspaces[ws]);
if(full_screen_workspace_tiles(server->output_layout, output->wlr_output,
if(full_screen_workspace_tiles(server->output_layout,
output->workspaces[ws],
&server->tiles_curr_id) != 0) {
wlr_log(WLR_ERROR, "Failed to allocate space for fullscreen workspace");
@ -516,58 +541,85 @@ handle_new_output(struct wl_listener *listener, void *data) {
return;
}
struct cg_output *output = calloc(1, sizeof(struct cg_output));
struct cg_output *ito;
bool reinit = false;
struct cg_output *output = NULL;
wl_list_for_each(ito, &server->outputs, link) {
if((strcmp(ito->name, wlr_output->name) == 0) && (ito->destroyed)) {
reinit = true;
output = ito;
}
}
if(!reinit) {
output = calloc(1, sizeof(struct cg_output));
}
if(!output) {
wlr_log(WLR_ERROR, "Failed to allocate output");
return;
}
output->wlr_output = wlr_output;
output->server = server;
output->last_scanned_out_view = NULL;
output->destroyed = false;
struct cg_output_priorities *it;
int prio = -1;
wl_list_for_each(it, &server->output_priorities, link) {
if(strcmp(output->wlr_output->name, it->ident) == 0) {
prio = it->priority;
if(!reinit) {
output->server = server;
output->last_scanned_out_view = NULL;
output->name = strdup(wlr_output->name);
struct cg_output_priorities *it;
int prio = -1;
wl_list_for_each(it, &server->output_priorities, link) {
if(strcmp(output->name, it->ident) == 0) {
prio = it->priority;
}
}
}
output->priority = prio;
wlr_output_set_transform(wlr_output, WL_OUTPUT_TRANSFORM_NORMAL);
output->workspaces = NULL;
output->priority = prio;
wlr_output_set_transform(wlr_output, WL_OUTPUT_TRANSFORM_NORMAL);
output->workspaces = NULL;
wl_list_init(&output->messages);
wl_list_init(&output->messages);
if(!wlr_xcursor_manager_load(server->seat->xcursor_manager,
wlr_output->scale)) {
wlr_log(WLR_ERROR,
"Cannot load XCursor theme for output '%s' with scale %f",
wlr_output->name, wlr_output->scale);
}
output_insert(server, output);
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;
if(!wlr_xcursor_manager_load(server->seat->xcursor_manager,
wlr_output->scale)) {
wlr_log(WLR_ERROR,
"Cannot load XCursor theme for output '%s' with scale %f",
output->name, wlr_output->scale);
}
output->workspaces[i]->num = i;
wl_list_init(&output->workspaces[i]->views);
wl_list_init(&output->workspaces[i]->unmanaged_views);
output_insert(server, output);
output_configure(server, output);
wlr_output_layout_get_box(server->output_layout, output->wlr_output,
&output->layout_box);
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;
}
output->workspaces[i]->num = i;
wl_list_init(&output->workspaces[i]->views);
wl_list_init(&output->workspaces[i]->unmanaged_views);
}
wlr_scene_node_raise_to_top(&output->workspaces[0]->scene->node);
workspace_focus(output, 0);
/* We are the first output. Set the current output to this one. */
if(server->curr_output == NULL) {
server->curr_output = output;
}
} else {
wlr_output_layout_add(server->output_layout, wlr_output,
output_get_layout_box(output).x,
output_get_layout_box(output).y);
output_configure(server, output);
wlr_output_layout_get_box(server->output_layout, output->wlr_output,
&output->layout_box);
}
wlr_scene_node_raise_to_top(&output->workspaces[0]->scene->node);
workspace_focus(output, 0);
/* We are the first output. Set the current output to this one. */
if(server->curr_output == NULL) {
server->curr_output = output;
}
wlr_xcursor_manager_set_cursor_image(server->seat->xcursor_manager,
DEFAULT_XCURSOR, server->seat->cursor);
wlr_cursor_warp(server->seat->cursor, NULL, 0, 0);
@ -580,11 +632,12 @@ handle_new_output(struct wl_listener *listener, void *data) {
wl_signal_add(&wlr_output->events.commit, &output->commit);
output->mode.notify = handle_output_mode;
wl_signal_add(&wlr_output->events.mode, &output->mode);
ipc_send_event(server,
"{\"event_name\":\"new_output\",\"output\":\"%s\",\"output_"
"id\":%d,\"priority\":%d}",
output->wlr_output->name, output_get_num(output),
output->priority);
"id\":%d,\"priority\":%d,\"restart\":%d}",
output->name, output_get_num(output), output->priority,
reinit);
}
#if CG_HAS_FANALYZE
#pragma GCC diagnostic pop

View file

@ -12,6 +12,12 @@ struct cg_view;
struct wlr_output;
struct wlr_surface;
enum output_role {
OUTPUT_ROLE_PERIPHERAL,
OUTPUT_ROLE_PERMANENT,
OUTPUT_ROLE_DEFAULT
};
struct cg_output {
struct cg_server *server;
struct wlr_output *wlr_output;
@ -23,9 +29,13 @@ struct cg_output {
struct wl_listener frame;
struct cg_workspace **workspaces;
struct wl_list messages;
struct wlr_box layout_box;
int curr_workspace;
int priority;
struct cg_view *last_scanned_out_view;
enum output_role role;
bool destroyed;
char *name;
struct wl_list link; // cg_server::outputs
};
@ -40,6 +50,7 @@ enum output_status { OUTPUT_ENABLE, OUTPUT_DISABLE, OUTPUT_DEFAULT };
struct cg_output_config {
enum output_status status;
enum output_role role;
struct wlr_box pos;
char *output_name;
float refresh_rate;
@ -53,7 +64,8 @@ typedef void (*cg_surface_iterator_func_t)(struct cg_output *output,
struct wlr_surface *surface,
struct wlr_box *box,
void *user_data);
struct wlr_box
output_get_layout_box(struct cg_output *output);
void
handle_new_output(struct wl_listener *listener, void *data);
void

22
parse.c
View file

@ -543,6 +543,10 @@ parse_output_config_keyword(char *key_str, enum output_status *status) {
*status = OUTPUT_DEFAULT;
} else if(strcmp(key_str, "enable") == 0) {
*status = OUTPUT_ENABLE;
} else if(strcmp(key_str, "permanent") == 0) {
*status = OUTPUT_DEFAULT;
} else if(strcmp(key_str, "peripheral") == 0) {
*status = OUTPUT_DEFAULT;
} else if(strcmp(key_str, "disable") == 0) {
*status = OUTPUT_DISABLE;
} else {
@ -566,6 +570,7 @@ parse_output_config(char **saveptr, char **errstr) {
cfg->priority = -1;
cfg->scale = -1;
cfg->angle = -1;
cfg->role = OUTPUT_ROLE_DEFAULT;
char *name = strtok_r(NULL, " ", saveptr);
if(name == NULL) {
*errstr =
@ -574,8 +579,9 @@ parse_output_config(char **saveptr, char **errstr) {
}
char *key_str = strtok_r(NULL, " ", saveptr);
if(parse_output_config_keyword(key_str, &(cfg->status)) != 0) {
*errstr = log_error("Expected keyword \"pos\", \"prio\", \"enable\" or "
"\"disable\" in output configuration for output %s",
*errstr = log_error("Expected keyword \"pos\", \"prio\", \"enable\", "
"\"disable\", \"permanent\" or \"peripheral\" in "
"output configuration for output %s",
name);
goto error;
}
@ -622,6 +628,18 @@ parse_output_config(char **saveptr, char **errstr) {
return cfg;
}
if(strcmp(key_str, "peripheral") == 0) {
cfg->output_name = strdup(name);
cfg->role = OUTPUT_ROLE_PERIPHERAL;
return cfg;
}
if(strcmp(key_str, "permanent") == 0) {
cfg->output_name = strdup(name);
cfg->role = OUTPUT_ROLE_PERMANENT;
return cfg;
}
cfg->pos.x = parse_uint(saveptr, " ");
if(cfg->pos.x < 0) {
*errstr = log_error(

16
seat.c
View file

@ -95,7 +95,7 @@ new_touch(struct cg_seat *seat, struct cg_input_device *input_device) {
if(wlr_touch->output_name != NULL) {
struct cg_output *output;
wl_list_for_each(output, &seat->server->outputs, link) {
if(strcmp(wlr_touch->output_name, output->wlr_output->name) == 0) {
if(strcmp(wlr_touch->output_name, output->name) == 0) {
wlr_cursor_map_input_to_output(seat->cursor, device,
output->wlr_output);
break;
@ -133,8 +133,7 @@ new_pointer(struct cg_seat *seat, struct cg_input_device *input_device) {
if(wlr_pointer->output_name != NULL) {
struct cg_output *output;
wl_list_for_each(output, &seat->server->outputs, link) {
if(strcmp(wlr_pointer->output_name, output->wlr_output->name) ==
0) {
if(strcmp(wlr_pointer->output_name, output->name) == 0) {
wlr_cursor_map_input_to_output(seat->cursor, device,
output->wlr_output);
break;
@ -755,7 +754,7 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time) {
"\"%s\",\"old_output_id\":%d,"
"\"old_tile\":%d,\"new_output\":\"%s\",\"new_output_"
"id\":%d,\"new_tile\":%d}",
seat->cursor_tile->workspace->output->wlr_output->name,
seat->cursor_tile->workspace->output->name,
output_get_num(seat->cursor_tile->workspace->output),
seat->cursor_tile->id, c_outp->name,
output_get_num(cg_outp), c_tile->id);
@ -1095,9 +1094,8 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view) {
wlr_scene_node_raise_to_top(&view->scene_tree->node);
process_cursor_motion(seat, -1);
struct wlr_box box;
wlr_output_layout_get_box(server->output_layout,
view->workspace->output->wlr_output, &box);
wlr_scene_node_set_position(&view->workspace->output->bg->node, box.x,
box.y);
wlr_scene_node_set_position(
&view->workspace->output->bg->node,
output_get_layout_box(view->workspace->output).x,
output_get_layout_box(view->workspace->output).y);
}

View file

@ -43,8 +43,7 @@ server_show_info(struct cg_server *server) {
return NULL;
}
output_str_tmp = output_str;
output_str = malloc_vsprintf("%s\t * %s\n", output_str,
output->wlr_output->name);
output_str = malloc_vsprintf("%s\t * %s\n", output_str, output->name);
free(output_str_tmp);
}
char *input_str = strdup(""), *input_str_tmp;

24
view.c
View file

@ -81,11 +81,10 @@ void
view_maximize(struct cg_view *view, struct cg_tile *tile) {
view->ox = tile->tile.x;
view->oy = tile->tile.y;
struct wlr_box box;
wlr_output_layout_get_box(view->server->output_layout,
view->workspace->output->wlr_output, &box);
wlr_scene_node_set_position(&view->scene_tree->node, view->ox + box.x,
view->oy + box.y);
wlr_scene_node_set_position(
&view->scene_tree->node,
view->ox + output_get_layout_box(view->workspace->output).x,
output_get_layout_box(view->oy + view->workspace->output).y);
view->impl->maximize(view, tile->tile.width, tile->tile.height);
view->tile = tile;
wlr_scene_node_raise_to_top(&view->scene_tree->node);
@ -97,7 +96,7 @@ view_unmap(struct cg_view *view) {
uint32_t id = view->id;
uint32_t tile_id = 0;
uint32_t ws = view->workspace->num;
char *output_name = view->workspace->output->wlr_output->name;
char *output_name = view->workspace->output->name;
int output_id = output_get_num(view->workspace->output);
pid_t pid = view->impl->get_pid(view);
/* If the view is not mapped, do nothing */
@ -171,11 +170,10 @@ view_map(struct cg_view *view, struct wlr_surface *surface,
their own (x,y) coordinates in handle_wayland_surface_map. */
if(view->type == CG_XWAYLAND_VIEW && !xwayland_view_should_manage(view)) {
wl_list_insert(&ws->unmanaged_views, &view->link);
struct wlr_box box;
wlr_output_layout_get_box(view->server->output_layout,
view->workspace->output->wlr_output, &box);
wlr_scene_node_set_position(&view->scene_tree->node, view->ox + box.x,
view->oy + box.y);
wlr_scene_node_set_position(
&view->scene_tree->node,
view->ox + output_get_layout_box(view->workspace->output).x,
view->oy + output_get_layout_box(view->workspace->output).y);
} else
#endif
{
@ -193,8 +191,8 @@ view_map(struct cg_view *view, struct wlr_surface *surface,
"{\"event_name\":\"view_map\",\"view_id\":%d,\"tile_id\":%d,"
"\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d,\"view_pid\":%d}",
view->id, tile_id, view->workspace->num + 1,
view->workspace->output->wlr_output->name,
output_get_num(view->workspace->output), view->impl->get_pid(view));
view->workspace->output->name, output_get_num(view->workspace->output),
view->impl->get_pid(view));
}
void

View file

@ -35,7 +35,6 @@ workspace_tile_update_view(struct cg_tile *tile, struct cg_view *view) {
#endif
int
full_screen_workspace_tiles(struct wlr_output_layout *layout,
struct wlr_output *output,
struct cg_workspace *workspace,
uint32_t *tiles_curr_id) {
workspace->focused_tile = calloc(1, sizeof(struct cg_tile));
@ -47,10 +46,10 @@ full_screen_workspace_tiles(struct wlr_output_layout *layout,
workspace->focused_tile->prev = workspace->focused_tile;
workspace->focused_tile->tile.x = 0;
workspace->focused_tile->tile.y = 0;
struct wlr_box output_box;
wlr_output_layout_get_box(layout, output, &output_box);
workspace->focused_tile->tile.width = output_box.width;
workspace->focused_tile->tile.height = output_box.height;
workspace->focused_tile->tile.width =
output_get_layout_box(workspace->output).width;
workspace->focused_tile->tile.height =
output_get_layout_box(workspace->output).height;
workspace_tile_update_view(workspace->focused_tile, NULL);
workspace->focused_tile->id = *tiles_curr_id;
++(*tiles_curr_id);
@ -72,16 +71,15 @@ full_screen_workspace(struct cg_output *output) {
free(workspace);
return NULL;
}
workspace->output = output;
workspace->server = output->server;
workspace->num = -1;
workspace->scene = wlr_scene_tree_create(&scene_output->scene->tree);
if(full_screen_workspace_tiles(output->server->output_layout,
output->wlr_output, workspace,
if(full_screen_workspace_tiles(output->server->output_layout, workspace,
&output->server->tiles_curr_id) != 0) {
free(workspace);
return NULL;
}
workspace->output = output;
return workspace;
}
@ -107,7 +105,8 @@ workspace_free_tiles(struct cg_workspace *workspace) {
workspace->focused_tile) {
workspace->output->server->seat->cursor_tile = NULL;
}
if(workspace->focused_tile == workspace->server->seat->cursor_tile) {
if(workspace->output->server->running &&
workspace->focused_tile == workspace->server->seat->cursor_tile) {
workspace->server->seat->cursor_tile = NULL;
}
struct cg_tile *next = workspace->focused_tile->next;

View file

@ -33,7 +33,6 @@ struct cg_workspace *
full_screen_workspace(struct cg_output *output);
int
full_screen_workspace_tiles(struct wlr_output_layout *layout,
struct wlr_output *output,
struct cg_workspace *workspace,
uint32_t *tiles_curr_id);
void

View file

@ -74,12 +74,12 @@ popup_unconstrain(struct cg_view *view, struct wlr_xdg_popup *popup) {
struct wlr_box *popup_box = &popup->current.geometry;
struct wlr_output_layout *output_layout = view->server->output_layout;
struct wlr_box view_output_box;
wlr_output_layout_get_box(
output_layout, view->workspace->output->wlr_output, &view_output_box);
struct wlr_output *wlr_output = wlr_output_layout_output_at(
output_layout, view_output_box.x + view->ox + popup_box->x,
view_output_box.y + view->oy + popup_box->y);
output_layout,
output_get_layout_box(view->workspace->output).x + view->ox +
popup_box->x,
output_get_layout_box(view->workspace->output).y + view->oy +
popup_box->y);
struct wlr_box output_box;
wlr_output_layout_get_box(output_layout, wlr_output, &output_box);

View file

@ -93,13 +93,11 @@ maximize(struct cg_view *view, int width, int height) {
}
}
struct wlr_box output_box;
wlr_output_layout_get_box(view->server->output_layout,
view->server->curr_output->wlr_output,
&output_box);
wlr_xwayland_surface_configure(xwayland_view->xwayland_surface,
view->ox + output_box.x,
view->oy + output_box.y, width, height);
wlr_xwayland_surface_configure(
xwayland_view->xwayland_surface,
view->ox + output_get_layout_box(view->server->curr_output).x,
view->oy + output_get_layout_box(view->server->curr_output).y, width,
height);
wlr_xwayland_surface_set_maximized(xwayland_view->xwayland_surface, true);
}
@ -135,12 +133,10 @@ handle_xwayland_surface_map(struct wl_listener *listener, void *_data) {
wl_container_of(listener, xwayland_view, map);
struct cg_view *view = &xwayland_view->view;
if(!xwayland_view_should_manage(view)) {
struct wlr_output_layout *output_layout = view->server->output_layout;
struct wlr_box output_box;
wlr_output_layout_get_box(
output_layout, view->server->curr_output->wlr_output, &output_box);
view->ox = xwayland_view->xwayland_surface->x - output_box.x;
view->oy = xwayland_view->xwayland_surface->y - output_box.y;
view->ox = xwayland_view->xwayland_surface->x -
view->server->curr_output->layout_box.x;
view->oy = xwayland_view->xwayland_surface->y -
view->server->curr_output->layout_box.y;
}
view_map(view, xwayland_view->xwayland_surface->surface,