various fixes and code clean up stuff. improved frame management stability
This commit is contained in:
parent
65ab6842b8
commit
8532261b96
|
@ -2,3 +2,4 @@ build
|
||||||
fuzz_corpus
|
fuzz_corpus
|
||||||
fuzzing-directory
|
fuzzing-directory
|
||||||
PROGRESS.md
|
PROGRESS.md
|
||||||
|
TODO.md
|
||||||
|
|
37
nedm.c
37
nedm.c
|
@ -20,6 +20,7 @@
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
#include <wlr/backend/headless.h>
|
#include <wlr/backend/headless.h>
|
||||||
|
#include <wlr/backend/session.h>
|
||||||
#include <wlr/render/allocator.h>
|
#include <wlr/render/allocator.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
|
@ -119,12 +120,20 @@ handle_signal(int signal, void *const data) {
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
/* Fallthrough */
|
/* Fallthrough */
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
display_terminate(server);
|
if(server && server->wl_display) {
|
||||||
|
// Only terminate if we're sure the server is in a valid state
|
||||||
|
display_terminate(server);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case SIGALRM: {
|
case SIGALRM: {
|
||||||
struct nedm_output *output;
|
// Only clear messages if server is running and valid
|
||||||
wl_list_for_each(output, &server->outputs, link) {
|
if(server && server->running && !wl_list_empty(&server->outputs)) {
|
||||||
message_clear(output);
|
struct nedm_output *output;
|
||||||
|
wl_list_for_each(output, &server->outputs, link) {
|
||||||
|
if(output) {
|
||||||
|
message_clear(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -137,6 +146,7 @@ handle_signal(int signal, void *const data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(FILE *file, const char *const cage) {
|
usage(FILE *file, const char *const cage) {
|
||||||
fprintf(file,
|
fprintf(file,
|
||||||
|
@ -418,6 +428,14 @@ main(int argc, char *argv[]) {
|
||||||
wl_event_loop_add_signal(event_loop, SIGPIPE, handle_signal, &server);
|
wl_event_loop_add_signal(event_loop, SIGPIPE, handle_signal, &server);
|
||||||
server.event_loop = event_loop;
|
server.event_loop = event_loop;
|
||||||
|
|
||||||
|
// Let wlroots handle device selection automatically for better compatibility
|
||||||
|
const char *force_drm_device = getenv("WLR_DRM_DEVICES");
|
||||||
|
if (force_drm_device) {
|
||||||
|
wlr_log(WLR_INFO, "Using user-specified DRM devices: %s", force_drm_device);
|
||||||
|
} else {
|
||||||
|
wlr_log(WLR_DEBUG, "Using automatic DRM device selection");
|
||||||
|
}
|
||||||
|
|
||||||
backend = wlr_backend_autocreate(event_loop, &server.session);
|
backend = wlr_backend_autocreate(event_loop, &server.session);
|
||||||
server.headless_backend = wlr_headless_backend_create(event_loop);
|
server.headless_backend = wlr_headless_backend_create(event_loop);
|
||||||
if(!backend) {
|
if(!backend) {
|
||||||
|
@ -427,6 +445,15 @@ main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
server.backend = backend;
|
server.backend = backend;
|
||||||
|
|
||||||
|
// Session is handled automatically by wlroots - no custom handlers needed
|
||||||
|
if (server.session) {
|
||||||
|
server.session_is_active = true; // Start active
|
||||||
|
wlr_log(WLR_INFO, "Session available - VT switching handled by wlroots");
|
||||||
|
} else {
|
||||||
|
wlr_log(WLR_DEBUG, "No session available - running without VT switching");
|
||||||
|
server.session_is_active = true; // Fallback for sessionless operation
|
||||||
|
}
|
||||||
|
|
||||||
if(!drop_permissions()) {
|
if(!drop_permissions()) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -812,6 +839,8 @@ end:
|
||||||
seat_destroy(server.seat);
|
seat_destroy(server.seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Session cleanup handled automatically by wlroots
|
||||||
|
|
||||||
if(sigint_source != NULL) {
|
if(sigint_source != NULL) {
|
||||||
wl_event_source_remove(sigint_source);
|
wl_event_source_remove(sigint_source);
|
||||||
wl_event_source_remove(sigterm_source);
|
wl_event_source_remove(sigterm_source);
|
||||||
|
|
32
output.c
32
output.c
|
@ -71,6 +71,10 @@ output_clear(struct nedm_output *output) {
|
||||||
struct nedm_view *view, *view_tmp;
|
struct nedm_view *view, *view_tmp;
|
||||||
if(server->running) {
|
if(server->running) {
|
||||||
for(unsigned int i = 0; i < server->nws; ++i) {
|
for(unsigned int i = 0; i < server->nws; ++i) {
|
||||||
|
if(!output->workspaces || !output->workspaces[i] ||
|
||||||
|
!output->workspaces[i]->focused_tile) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for(struct nedm_tile *tile = output->workspaces[i]->focused_tile;
|
for(struct nedm_tile *tile = output->workspaces[i]->focused_tile;
|
||||||
|
@ -79,20 +83,23 @@ output_clear(struct nedm_output *output) {
|
||||||
first = false;
|
first = false;
|
||||||
workspace_tile_update_view(tile, NULL);
|
workspace_tile_update_view(tile, NULL);
|
||||||
}
|
}
|
||||||
struct nedm_workspace *ws =
|
struct nedm_workspace *ws = NULL;
|
||||||
server->curr_output
|
if(server->curr_output && server->curr_output->workspaces &&
|
||||||
->workspaces[server->curr_output->curr_workspace];
|
server->curr_output->curr_workspace < server->nws &&
|
||||||
|
server->curr_output->workspaces[server->curr_output->curr_workspace]) {
|
||||||
|
ws = server->curr_output->workspaces[server->curr_output->curr_workspace];
|
||||||
|
}
|
||||||
wl_list_for_each_safe(view, view_tmp, &output->workspaces[i]->views,
|
wl_list_for_each_safe(view, view_tmp, &output->workspaces[i]->views,
|
||||||
link) {
|
link) {
|
||||||
wl_list_remove(&view->link);
|
wl_list_remove(&view->link);
|
||||||
if(wl_list_empty(&server->outputs)) {
|
if(wl_list_empty(&server->outputs)) {
|
||||||
view->impl->destroy(view);
|
view->impl->destroy(view);
|
||||||
} else {
|
} else if(ws) {
|
||||||
wl_list_insert(&ws->views, &view->link);
|
wl_list_insert(&ws->views, &view->link);
|
||||||
wlr_scene_node_reparent(&view->scene_tree->node, ws->scene);
|
wlr_scene_node_reparent(&view->scene_tree->node, ws->scene);
|
||||||
view->workspace = ws;
|
view->workspace = ws;
|
||||||
view->tile = ws->focused_tile;
|
view->tile = ws->focused_tile;
|
||||||
if(server->seat->focused_view == NULL) {
|
if(server->seat && server->seat->focused_view == NULL) {
|
||||||
seat_set_focus(server->seat, view);
|
seat_set_focus(server->seat, view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,8 +204,13 @@ output_destroy(struct nedm_output *output) {
|
||||||
wlr_log(WLR_ERROR,
|
wlr_log(WLR_ERROR,
|
||||||
"Failed to allocate memory for output name in output_destroy");
|
"Failed to allocate memory for output name in output_destroy");
|
||||||
}
|
}
|
||||||
|
// Note: Don't terminate when outputs become empty - this is normal during:
|
||||||
|
// - VT switches (outputs temporarily disabled)
|
||||||
|
// - Output hotplug events
|
||||||
|
// - Multi-GPU switching
|
||||||
|
// Modern compositors handle this gracefully and wait for outputs to return
|
||||||
if(wl_list_empty(&server->outputs) && server->running) {
|
if(wl_list_empty(&server->outputs) && server->running) {
|
||||||
wl_display_terminate(server->wl_display);
|
wlr_log(WLR_DEBUG, "No outputs available - waiting for outputs to return");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,9 +624,13 @@ output_make_workspace_fullscreen(struct nedm_output *output, uint32_t ws) {
|
||||||
if(ws >= server->nws) {
|
if(ws >= server->nws) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct nedm_view *current_view = output->workspaces[ws]->focused_tile->view;
|
struct nedm_view *current_view = NULL;
|
||||||
|
if(output->workspaces && ws < output->server->nws &&
|
||||||
|
output->workspaces[ws] && output->workspaces[ws]->focused_tile) {
|
||||||
|
current_view = output->workspaces[ws]->focused_tile->view;
|
||||||
|
}
|
||||||
|
|
||||||
if(current_view == NULL) {
|
if(current_view == NULL && output->workspaces[ws]) {
|
||||||
struct nedm_view *it = NULL;
|
struct nedm_view *it = NULL;
|
||||||
wl_list_for_each(it, &output->workspaces[ws]->views, link) {
|
wl_list_for_each(it, &output->workspaces[ws]->views, link) {
|
||||||
if(view_is_visible(it)) {
|
if(view_is_visible(it)) {
|
||||||
|
|
18
seat.c
18
seat.c
|
@ -803,7 +803,10 @@ process_cursor_motion(struct nedm_seat *seat, uint32_t time) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(c_outp) {
|
if(c_outp && nedm_outp->workspaces &&
|
||||||
|
nedm_outp->curr_workspace < nedm_outp->server->nws &&
|
||||||
|
nedm_outp->workspaces[nedm_outp->curr_workspace] &&
|
||||||
|
nedm_outp->workspaces[nedm_outp->curr_workspace]->focused_tile) {
|
||||||
struct nedm_tile *c_tile;
|
struct nedm_tile *c_tile;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for(c_tile = nedm_outp->workspaces[nedm_outp->curr_workspace]->focused_tile;
|
for(c_tile = nedm_outp->workspaces[nedm_outp->curr_workspace]->focused_tile;
|
||||||
|
@ -1184,10 +1187,15 @@ seat_set_focus(struct nedm_seat *seat, struct nedm_view *view) {
|
||||||
|
|
||||||
/* Focusing the background */
|
/* Focusing the background */
|
||||||
if(view == NULL) {
|
if(view == NULL) {
|
||||||
workspace_tile_update_view(
|
if(server->curr_output && server->curr_output->workspaces &&
|
||||||
server->curr_output->workspaces[server->curr_output->curr_workspace]
|
server->curr_output->curr_workspace < server->nws &&
|
||||||
->focused_tile,
|
server->curr_output->workspaces[server->curr_output->curr_workspace] &&
|
||||||
NULL);
|
server->curr_output->workspaces[server->curr_output->curr_workspace]->focused_tile) {
|
||||||
|
workspace_tile_update_view(
|
||||||
|
server->curr_output->workspaces[server->curr_output->curr_workspace]
|
||||||
|
->focused_tile,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
seat->focused_view = NULL;
|
seat->focused_view = NULL;
|
||||||
if(prev_view != NULL) {
|
if(prev_view != NULL) {
|
||||||
view_activate(prev_view, false);
|
view_activate(prev_view, false);
|
||||||
|
|
10
server.c
10
server.c
|
@ -66,3 +66,13 @@ server_show_info(struct nedm_server *server) {
|
||||||
free(input_str);
|
free(input_str);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
server_session_is_active(struct nedm_server *server) {
|
||||||
|
if (!server) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// wlroots handles session state automatically
|
||||||
|
// Just return our tracked state for output termination logic
|
||||||
|
return server->session_is_active;
|
||||||
|
}
|
||||||
|
|
4
server.h
4
server.h
|
@ -44,6 +44,8 @@ struct nedm_server {
|
||||||
struct wl_list output_priorities;
|
struct wl_list output_priorities;
|
||||||
struct wlr_backend *headless_backend;
|
struct wlr_backend *headless_backend;
|
||||||
struct wlr_session *session;
|
struct wlr_session *session;
|
||||||
|
struct wl_listener session_active;
|
||||||
|
bool session_is_active;
|
||||||
|
|
||||||
struct wlr_renderer *renderer;
|
struct wlr_renderer *renderer;
|
||||||
struct wlr_allocator *allocator;
|
struct wlr_allocator *allocator;
|
||||||
|
@ -90,5 +92,7 @@ int
|
||||||
get_mode_index_from_name(char *const *modes, const char *mode_name);
|
get_mode_index_from_name(char *const *modes, const char *mode_name);
|
||||||
char *
|
char *
|
||||||
server_show_info(struct nedm_server *server);
|
server_show_info(struct nedm_server *server);
|
||||||
|
bool
|
||||||
|
server_session_is_active(struct nedm_server *server);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
47
view.c
47
view.c
|
@ -131,13 +131,16 @@ view_unmap(struct nedm_view *view) {
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
struct nedm_view *prev = view_get_prev_view(view);
|
struct nedm_view *prev = view_get_prev_view(view);
|
||||||
if(view == view->server->seat->focused_view) {
|
if(view->server && view->server->seat) {
|
||||||
seat_set_focus(view->server->seat, prev);
|
if(view == view->server->seat->focused_view) {
|
||||||
} else if(view->server->seat->seat->keyboard_state.focused_surface ==
|
seat_set_focus(view->server->seat, prev);
|
||||||
view->wlr_surface) {
|
} else if(view->server->seat->seat &&
|
||||||
wlr_seat_keyboard_clear_focus(view->server->seat->seat);
|
view->server->seat->seat->keyboard_state.focused_surface ==
|
||||||
seat_set_focus(view->server->seat,
|
view->wlr_surface) {
|
||||||
view->server->seat->focused_view);
|
wlr_seat_keyboard_clear_focus(view->server->seat->seat);
|
||||||
|
seat_set_focus(view->server->seat,
|
||||||
|
view->server->seat->focused_view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
struct nedm_tile *view_tile = view_get_tile(view);
|
struct nedm_tile *view_tile = view_get_tile(view);
|
||||||
if(view_tile != NULL) {
|
if(view_tile != NULL) {
|
||||||
|
@ -146,11 +149,13 @@ view_unmap(struct nedm_view *view) {
|
||||||
}
|
}
|
||||||
#if NEDM_HAS_XWAYLAND
|
#if NEDM_HAS_XWAYLAND
|
||||||
else {
|
else {
|
||||||
if(view->server->seat->seat->keyboard_state.focused_surface == NULL ||
|
if(view->server && view->server->seat && view->server->seat->seat) {
|
||||||
view->server->seat->seat->keyboard_state.focused_surface ==
|
if(view->server->seat->seat->keyboard_state.focused_surface == NULL ||
|
||||||
view->wlr_surface) {
|
view->server->seat->seat->keyboard_state.focused_surface ==
|
||||||
seat_set_focus(view->server->seat,
|
view->wlr_surface) {
|
||||||
view->server->seat->focused_view);
|
seat_set_focus(view->server->seat,
|
||||||
|
view->server->seat->focused_view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -193,7 +198,9 @@ view_map(struct nedm_view *view, struct wlr_surface *surface,
|
||||||
{
|
{
|
||||||
wl_list_insert(&ws->views, &view->link);
|
wl_list_insert(&ws->views, &view->link);
|
||||||
}
|
}
|
||||||
seat_set_focus(output->server->seat, view);
|
if(output && output->server && output->server->seat) {
|
||||||
|
seat_set_focus(output->server->seat, view);
|
||||||
|
}
|
||||||
int tile_id = 0;
|
int tile_id = 0;
|
||||||
if(view->tile == NULL) {
|
if(view->tile == NULL) {
|
||||||
tile_id = -1;
|
tile_id = -1;
|
||||||
|
@ -219,9 +226,17 @@ view_destroy(struct nedm_view *view) {
|
||||||
wlr_scene_node_destroy(&view->scene_tree->node);
|
wlr_scene_node_destroy(&view->scene_tree->node);
|
||||||
|
|
||||||
view->impl->destroy(view);
|
view->impl->destroy(view);
|
||||||
view_activate(curr_output->workspaces[curr_output->curr_workspace]
|
|
||||||
->focused_tile->view,
|
// Safely activate the focused view if it exists
|
||||||
true);
|
if(curr_output && curr_output->workspaces &&
|
||||||
|
curr_output->curr_workspace < curr_output->server->nws &&
|
||||||
|
curr_output->workspaces[curr_output->curr_workspace] &&
|
||||||
|
curr_output->workspaces[curr_output->curr_workspace]->focused_tile &&
|
||||||
|
curr_output->workspaces[curr_output->curr_workspace]->focused_tile->view) {
|
||||||
|
view_activate(curr_output->workspaces[curr_output->curr_workspace]
|
||||||
|
->focused_tile->view,
|
||||||
|
true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue