From cda1d645d23370305b2aa02a0a385cd126d47e30 Mon Sep 17 00:00:00 2001 From: project-repo Date: Mon, 12 Sep 2022 07:36:36 +0200 Subject: [PATCH 1/4] Attempt fallback disable --- output.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/output.c b/output.c index 66b644f..6df0cc0 100644 --- a/output.c +++ b/output.c @@ -182,7 +182,7 @@ output_find_config(struct cg_server *server, struct wlr_output *output) { return NULL; } -static void +static int output_set_mode(struct wlr_output *output, int width, int height, float refresh_rate) { int mhz = (int)(refresh_rate * 1000); @@ -191,7 +191,7 @@ output_set_mode(struct wlr_output *output, int width, int height, wlr_log(WLR_DEBUG, "Assigning custom mode to %s", output->name); wlr_output_set_custom_mode(output, width, height, refresh_rate > 0 ? mhz : 0); - return; + return 0; } struct wlr_output_mode *mode, *best = NULL; @@ -228,6 +228,10 @@ output_set_mode(struct wlr_output *output, int width, int height, } } } + if(!wlr_output_test(output)) { + return 1; + } + return 0; } void @@ -290,8 +294,14 @@ output_configure(struct cg_server *server, struct cg_output *output) { output->priority = config->priority; } if(config->pos.x != -1) { - output_set_mode(wlr_output, config->pos.width, - config->pos.height, config->refresh_rate); + if(output_set_mode(wlr_output, config->pos.width, + config->pos.height, config->refresh_rate)!=0) { + output_clear(output); + wl_list_insert(&server->disabled_outputs,&output->link); + wlr_output_enable(wlr_output, false); + wlr_output_commit(wlr_output); + return; + } wlr_output_layout_add(server->output_layout, wlr_output, config->pos.x, config->pos.y); } From 3b5b85070fbabaf7f4ce6d4bbc869d08b6722ccf Mon Sep 17 00:00:00 2001 From: project-repo Date: Sun, 18 Sep 2022 10:22:08 +0200 Subject: [PATCH 2/4] Fix sizing of reconfigured outputs --- keybinding.c | 33 ++--------------------- message.c | 6 ++++- output.c | 74 ++++++++++++++++++++++++++++++++++++++++++---------- output.h | 4 +-- workspace.c | 6 ++++- 5 files changed, 74 insertions(+), 49 deletions(-) diff --git a/keybinding.c b/keybinding.c index 2cca163..6b23e65 100644 --- a/keybinding.c +++ b/keybinding.c @@ -466,38 +466,9 @@ resize_tile(struct cg_server *server, int hpixs, int vpixs) { void keybinding_workspace_fullscreen(struct cg_server *server) { - struct cg_view *current_view = seat_get_focus(server->seat); + output_make_workspace_fullscreen(server->curr_output,server->curr_output->curr_workspace); struct cg_output *output = server->curr_output; - - /* We are focused on the background */ - if(current_view == NULL) { - struct cg_view *it = NULL; - wl_list_for_each(it, &output->workspaces[output->curr_workspace]->views, - link) { - if(view_is_visible(it)) { - current_view = it; - break; - } - } - } - - workspace_free_tiles(output->workspaces[output->curr_workspace]); - if(full_screen_workspace_tiles(server->output_layout, output->wlr_output, - output->workspaces[output->curr_workspace], - &server->tiles_curr_id) != 0) { - wlr_log(WLR_ERROR, "Failed to allocate space for fullscreen workspace"); - return; - } - - struct cg_view *it_view; - wl_list_for_each(it_view, - &output->workspaces[output->curr_workspace]->views, link) { - it_view->tile = - output->workspaces[output->curr_workspace]->focused_tile; - } - - seat_set_focus(server->seat, current_view); - ipc_send_event(output->server, + ipc_send_event(server, "{\"event_name\":\"fullscreen\",\"tile_id\":\"%d\",\"workspace\":\"%d\",\"output\":\"%s\"}", output->workspaces[output->curr_workspace]->focused_tile->id, output->workspaces[output->curr_workspace]->num + 1, diff --git a/message.c b/message.c index 8e8e0d1..617f91d 100644 --- a/message.c +++ b/message.c @@ -217,7 +217,11 @@ message_set_output(struct cg_output *output, const char *string, break; } - message->message=wlr_scene_buffer_create(&output->scene_output->scene->node,&buf->base); + struct wlr_scene_output *scene_output = wlr_scene_get_scene_output(output->server->scene,output->wlr_output); + if(scene_output == NULL) { + return; + } + message->message=wlr_scene_buffer_create(&scene_output->scene->node,&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( diff --git a/output.c b/output.c index 6df0cc0..98ce334 100644 --- a/output.c +++ b/output.c @@ -164,11 +164,15 @@ handle_output_frame(struct wl_listener *listener, void *data) { if(!output->wlr_output->enabled) { return; } - wlr_scene_output_commit(output->scene_output); + struct wlr_scene_output *scene_output=wlr_scene_get_scene_output(output->server->scene,output->wlr_output); + if(scene_output == NULL) { + return; + } + wlr_scene_output_commit(scene_output); struct timespec now={0}; clock_gettime(CLOCK_MONOTONIC, &now); - wlr_scene_output_send_frame_done(output->scene_output, &now); + wlr_scene_output_send_frame_done(scene_output, &now); } struct cg_output_config * @@ -215,6 +219,7 @@ output_set_mode(struct wlr_output *output, int width, int height, wlr_log(WLR_DEBUG, "Assigning configured mode to %s", output->name); } wlr_output_set_mode(output, best); + wlr_output_commit(output); if(!wlr_output_test(output)) { wlr_log(WLR_ERROR, "Unable to assign configured mode to %s, picking arbitrary available mode",output->name); struct wlr_output_mode *mode; @@ -223,13 +228,14 @@ output_set_mode(struct wlr_output *output, int width, int height, continue; } wlr_output_set_mode(output, mode); + wlr_output_commit(output); if(wlr_output_test(output)) { break; } } - } - if(!wlr_output_test(output)) { - return 1; + if(!wlr_output_test(output)) { + return 1; + } } return 0; } @@ -289,13 +295,13 @@ output_configure(struct cg_server *server, struct cg_output *output) { wlr_output_enable(wlr_output, false); wlr_output_commit(wlr_output); } else { - wl_list_remove(&output->link); if(config->priority != -1) { output->priority = config->priority; } if(config->pos.x != -1) { if(output_set_mode(wlr_output, config->pos.width, config->pos.height, config->refresh_rate)!=0) { + wlr_log(WLR_ERROR,"Setting output mode failed, disabling output."); output_clear(output); wl_list_insert(&server->disabled_outputs,&output->link); wlr_output_enable(wlr_output, false); @@ -304,23 +310,26 @@ output_configure(struct cg_server *server, struct cg_output *output) { } wlr_output_layout_add(server->output_layout, wlr_output, config->pos.x, config->pos.y); + /* Since the size of the output may have changed, we reinitialize all workspaces with a fullscreen layout */ + for(unsigned int i = 0; i < output->server->nws; ++i) { + output_make_workspace_fullscreen(output,i); + } } + wl_list_remove(&output->link); output_insert(server, output); wlr_output_enable(wlr_output, true); wlr_output_commit(wlr_output); } } - struct wlr_scene_output *scene_output; - wl_list_for_each(scene_output,&output->server->scene->outputs,link) { - if(scene_output->output == wlr_output) { - output->scene_output=scene_output; - break; - } - } if(output->bg!=NULL) { wlr_scene_node_destroy(&output->bg->node); + output->bg=NULL; } - output->bg=wlr_scene_rect_create(&output->scene_output->scene->node, output->wlr_output->width,output->wlr_output->height, server->bg_color); + struct wlr_scene_output *scene_output = wlr_scene_get_scene_output(output->server->scene,output->wlr_output); + if(scene_output == NULL) { + return; + } + output->bg=wlr_scene_rect_create(&scene_output->scene->node, 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); wlr_scene_node_set_position(&output->bg->node, box->x, box->y); @@ -365,6 +374,43 @@ handle_output_mode(struct wl_listener *listener, void *data) { } } +void +output_make_workspace_fullscreen(struct cg_output *output,int ws) { + struct cg_server *server=output->server; + struct cg_view *current_view = seat_get_focus(server->seat); + + /* We are focused on the background */ + if(current_view == NULL||ws != output->curr_workspace) { + struct cg_view *it = NULL; + wl_list_for_each(it, &output->workspaces[ws]->views, + link) { + if(view_is_visible(it)) { + current_view = it; + break; + } + } + } + + workspace_free_tiles(output->workspaces[ws]); + if(full_screen_workspace_tiles(server->output_layout, output->wlr_output, + output->workspaces[ws], + &server->tiles_curr_id) != 0) { + wlr_log(WLR_ERROR, "Failed to allocate space for fullscreen workspace"); + return; + } + + struct cg_view *it_view; + wl_list_for_each(it_view, &output->workspaces[ws]->views, link) { + it_view->tile = output->workspaces[ws]->focused_tile; + } + + if(ws == output->curr_workspace) { + seat_set_focus(server->seat, current_view); + } +} + + + #if CG_HAS_FANALYZE #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" diff --git a/output.h b/output.h index 787efdd..492700a 100644 --- a/output.h +++ b/output.h @@ -12,7 +12,6 @@ struct wlr_surface; struct cg_output { struct cg_server *server; struct wlr_output *wlr_output; - struct wlr_scene_output *scene_output; struct wlr_scene_rect *bg; struct wl_listener mode; @@ -56,5 +55,6 @@ void output_configure(struct cg_server *server, struct cg_output *output); void output_set_window_title(struct cg_output *output, const char *title); - +void +output_make_workspace_fullscreen(struct cg_output *output,int ws); #endif diff --git a/workspace.c b/workspace.c index 4000545..15de290 100644 --- a/workspace.c +++ b/workspace.c @@ -56,9 +56,13 @@ full_screen_workspace(struct cg_output *output) { if(!workspace) { return NULL; } + struct wlr_scene_output *scene_output=wlr_scene_get_scene_output(output->server->scene,output->wlr_output); + if(scene_output == NULL) { + return NULL; + } workspace->server = output->server; workspace->num = -1; - workspace->scene = wlr_scene_tree_create(&output->scene_output->scene->node); + workspace->scene = wlr_scene_tree_create(&scene_output->scene->node); if(full_screen_workspace_tiles(output->server->output_layout, output->wlr_output, workspace, &output->server->tiles_curr_id) != 0) { From bc9c7a7555e0ece9335425c135ea218fae98b7ff Mon Sep 17 00:00:00 2001 From: project-repo Date: Wed, 21 Sep 2022 19:17:17 +0200 Subject: [PATCH 3/4] Add restack to xwayland view activation --- xwayland.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xwayland.c b/xwayland.c index c3c3a57..5d609ae 100644 --- a/xwayland.c +++ b/xwayland.c @@ -63,6 +63,9 @@ static void activate(struct cg_view *view, bool activate) { struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view); wlr_xwayland_surface_activate(xwayland_view->xwayland_surface, activate); + if(activate) { + wlr_xwayland_surface_restack(xwayland_view->xwayland_surface, NULL, XCB_STACK_MODE_ABOVE); + } } static void From 5305eead4cf5da59832a2bd1a1eb520096d21d03 Mon Sep 17 00:00:00 2001 From: project-repo Date: Thu, 22 Sep 2022 19:38:28 +0200 Subject: [PATCH 4/4] Add IPC event for cursor switching output --- seat.c | 6 ++++++ seat.h | 1 + 2 files changed, 7 insertions(+) diff --git a/seat.c b/seat.c index 4f82743..6ce57ec 100644 --- a/seat.c +++ b/seat.c @@ -652,6 +652,12 @@ handle_cursor_motion(struct wl_listener *listener, void *data) { event->delta_y); process_cursor_motion(seat, event->time_msec); wlr_idle_notify_activity(seat->server->idle, seat->seat); + struct wlr_output *c_outp = wlr_output_layout_output_at(seat->server->output_layout,seat->cursor->x,seat->cursor->y); + if(seat->cursor_output != NULL && seat->cursor_output != c_outp) { + ipc_send_event(seat->server, "{\"event_name\":\"cursor_switch_output\",\"old_output\":\"%s\",\"new_output\":\"%s\"}", + seat->cursor_output->name, c_outp->name); + } + seat->cursor_output=c_outp; } static void diff --git a/seat.h b/seat.h index a46348b..66474b6 100644 --- a/seat.h +++ b/seat.h @@ -28,6 +28,7 @@ struct cg_seat { uint16_t num_touch; struct wlr_cursor *cursor; + struct wlr_output *cursor_output; struct wlr_xcursor_manager *xcursor_manager; struct wl_listener cursor_motion; struct wl_listener cursor_motion_absolute;